OSDN Git Service

Merge "AOD: Track missed AOD time ticks" into oc-dev am: e7b581bca9
[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.DELETE_PACKAGES;
20 import static android.Manifest.permission.INSTALL_PACKAGES;
21 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
22 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
23 import static android.Manifest.permission.REQUEST_INSTALL_PACKAGES;
24 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25 import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
57 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
58 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
59 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
60 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
61 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
62 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
63 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
64 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
65 import static android.content.pm.PackageManager.MATCH_ALL;
66 import static android.content.pm.PackageManager.MATCH_ANY_USER;
67 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
68 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
69 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
70 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
71 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
72 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
73 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
74 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
75 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
76 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
77 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
78 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
79 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
80 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
81 import static android.content.pm.PackageManager.PERMISSION_DENIED;
82 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
83 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
84 import static android.content.pm.PackageParser.isApkFile;
85 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
86 import static android.system.OsConstants.O_CREAT;
87 import static android.system.OsConstants.O_RDWR;
88 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
89 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
90 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
91 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
92 import static com.android.internal.util.ArrayUtils.appendInt;
93 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
94 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
95 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
96 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
97 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
98 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
99 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
100 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
101 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
102 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
103 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
104
105 import android.Manifest;
106 import android.annotation.NonNull;
107 import android.annotation.Nullable;
108 import android.app.ActivityManager;
109 import android.app.AppOpsManager;
110 import android.app.IActivityManager;
111 import android.app.ResourcesManager;
112 import android.app.admin.IDevicePolicyManager;
113 import android.app.admin.SecurityLog;
114 import android.app.backup.IBackupManager;
115 import android.content.BroadcastReceiver;
116 import android.content.ComponentName;
117 import android.content.ContentResolver;
118 import android.content.Context;
119 import android.content.IIntentReceiver;
120 import android.content.Intent;
121 import android.content.IntentFilter;
122 import android.content.IntentSender;
123 import android.content.IntentSender.SendIntentException;
124 import android.content.ServiceConnection;
125 import android.content.pm.ActivityInfo;
126 import android.content.pm.ApplicationInfo;
127 import android.content.pm.AppsQueryHelper;
128 import android.content.pm.ChangedPackages;
129 import android.content.pm.ComponentInfo;
130 import android.content.pm.InstantAppRequest;
131 import android.content.pm.AuxiliaryResolveInfo;
132 import android.content.pm.FallbackCategoryProvider;
133 import android.content.pm.FeatureInfo;
134 import android.content.pm.IOnPermissionsChangeListener;
135 import android.content.pm.IPackageDataObserver;
136 import android.content.pm.IPackageDeleteObserver;
137 import android.content.pm.IPackageDeleteObserver2;
138 import android.content.pm.IPackageInstallObserver2;
139 import android.content.pm.IPackageInstaller;
140 import android.content.pm.IPackageManager;
141 import android.content.pm.IPackageMoveObserver;
142 import android.content.pm.IPackageStatsObserver;
143 import android.content.pm.InstantAppInfo;
144 import android.content.pm.InstantAppResolveInfo;
145 import android.content.pm.InstrumentationInfo;
146 import android.content.pm.IntentFilterVerificationInfo;
147 import android.content.pm.KeySet;
148 import android.content.pm.PackageCleanItem;
149 import android.content.pm.PackageInfo;
150 import android.content.pm.PackageInfoLite;
151 import android.content.pm.PackageInstaller;
152 import android.content.pm.PackageManager;
153 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
154 import android.content.pm.PackageManagerInternal;
155 import android.content.pm.PackageParser;
156 import android.content.pm.PackageParser.ActivityIntentInfo;
157 import android.content.pm.PackageParser.PackageLite;
158 import android.content.pm.PackageParser.PackageParserException;
159 import android.content.pm.PackageStats;
160 import android.content.pm.PackageUserState;
161 import android.content.pm.ParceledListSlice;
162 import android.content.pm.PermissionGroupInfo;
163 import android.content.pm.PermissionInfo;
164 import android.content.pm.ProviderInfo;
165 import android.content.pm.ResolveInfo;
166 import android.content.pm.ServiceInfo;
167 import android.content.pm.SharedLibraryInfo;
168 import android.content.pm.Signature;
169 import android.content.pm.UserInfo;
170 import android.content.pm.VerifierDeviceIdentity;
171 import android.content.pm.VerifierInfo;
172 import android.content.pm.VersionedPackage;
173 import android.content.res.Resources;
174 import android.database.ContentObserver;
175 import android.graphics.Bitmap;
176 import android.hardware.display.DisplayManager;
177 import android.net.Uri;
178 import android.os.Binder;
179 import android.os.Build;
180 import android.os.Bundle;
181 import android.os.Debug;
182 import android.os.Environment;
183 import android.os.Environment.UserEnvironment;
184 import android.os.FileUtils;
185 import android.os.Handler;
186 import android.os.IBinder;
187 import android.os.Looper;
188 import android.os.Message;
189 import android.os.Parcel;
190 import android.os.ParcelFileDescriptor;
191 import android.os.PatternMatcher;
192 import android.os.Process;
193 import android.os.RemoteCallbackList;
194 import android.os.RemoteException;
195 import android.os.ResultReceiver;
196 import android.os.SELinux;
197 import android.os.ServiceManager;
198 import android.os.ShellCallback;
199 import android.os.SystemClock;
200 import android.os.SystemProperties;
201 import android.os.Trace;
202 import android.os.UserHandle;
203 import android.os.UserManager;
204 import android.os.UserManagerInternal;
205 import android.os.storage.IStorageManager;
206 import android.os.storage.StorageEventListener;
207 import android.os.storage.StorageManager;
208 import android.os.storage.StorageManagerInternal;
209 import android.os.storage.VolumeInfo;
210 import android.os.storage.VolumeRecord;
211 import android.provider.Settings.Global;
212 import android.provider.Settings.Secure;
213 import android.security.KeyStore;
214 import android.security.SystemKeyStore;
215 import android.service.pm.PackageServiceDumpProto;
216 import android.system.ErrnoException;
217 import android.system.Os;
218 import android.text.TextUtils;
219 import android.text.format.DateUtils;
220 import android.util.ArrayMap;
221 import android.util.ArraySet;
222 import android.util.Base64;
223 import android.util.BootTimingsTraceLog;
224 import android.util.DisplayMetrics;
225 import android.util.EventLog;
226 import android.util.ExceptionUtils;
227 import android.util.Log;
228 import android.util.LogPrinter;
229 import android.util.MathUtils;
230 import android.util.PackageUtils;
231 import android.util.Pair;
232 import android.util.PrintStreamPrinter;
233 import android.util.Slog;
234 import android.util.SparseArray;
235 import android.util.SparseBooleanArray;
236 import android.util.SparseIntArray;
237 import android.util.Xml;
238 import android.util.jar.StrictJarFile;
239 import android.util.proto.ProtoOutputStream;
240 import android.view.Display;
241
242 import com.android.internal.R;
243 import com.android.internal.annotations.GuardedBy;
244 import com.android.internal.app.IMediaContainerService;
245 import com.android.internal.app.ResolverActivity;
246 import com.android.internal.content.NativeLibraryHelper;
247 import com.android.internal.content.PackageHelper;
248 import com.android.internal.logging.MetricsLogger;
249 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
250 import com.android.internal.os.IParcelFileDescriptorFactory;
251 import com.android.internal.os.RoSystemProperties;
252 import com.android.internal.os.SomeArgs;
253 import com.android.internal.os.Zygote;
254 import com.android.internal.telephony.CarrierAppUtils;
255 import com.android.internal.util.ArrayUtils;
256 import com.android.internal.util.ConcurrentUtils;
257 import com.android.internal.util.DumpUtils;
258 import com.android.internal.util.FastPrintWriter;
259 import com.android.internal.util.FastXmlSerializer;
260 import com.android.internal.util.IndentingPrintWriter;
261 import com.android.internal.util.Preconditions;
262 import com.android.internal.util.XmlUtils;
263 import com.android.server.AttributeCache;
264 import com.android.server.DeviceIdleController;
265 import com.android.server.EventLogTags;
266 import com.android.server.FgThread;
267 import com.android.server.IntentResolver;
268 import com.android.server.LocalServices;
269 import com.android.server.LockGuard;
270 import com.android.server.ServiceThread;
271 import com.android.server.SystemConfig;
272 import com.android.server.SystemServerInitThreadPool;
273 import com.android.server.Watchdog;
274 import com.android.server.net.NetworkPolicyManagerInternal;
275 import com.android.server.pm.Installer.InstallerException;
276 import com.android.server.pm.PermissionsState.PermissionState;
277 import com.android.server.pm.Settings.DatabaseVersion;
278 import com.android.server.pm.Settings.VersionInfo;
279 import com.android.server.pm.dex.DexManager;
280 import com.android.server.storage.DeviceStorageMonitorInternal;
281
282 import dalvik.system.CloseGuard;
283 import dalvik.system.DexFile;
284 import dalvik.system.VMRuntime;
285
286 import libcore.io.IoUtils;
287 import libcore.util.EmptyArray;
288
289 import org.xmlpull.v1.XmlPullParser;
290 import org.xmlpull.v1.XmlPullParserException;
291 import org.xmlpull.v1.XmlSerializer;
292
293 import java.io.BufferedOutputStream;
294 import java.io.BufferedReader;
295 import java.io.ByteArrayInputStream;
296 import java.io.ByteArrayOutputStream;
297 import java.io.File;
298 import java.io.FileDescriptor;
299 import java.io.FileInputStream;
300 import java.io.FileOutputStream;
301 import java.io.FileReader;
302 import java.io.FilenameFilter;
303 import java.io.IOException;
304 import java.io.PrintWriter;
305 import java.nio.charset.StandardCharsets;
306 import java.security.DigestInputStream;
307 import java.security.MessageDigest;
308 import java.security.NoSuchAlgorithmException;
309 import java.security.PublicKey;
310 import java.security.SecureRandom;
311 import java.security.cert.Certificate;
312 import java.security.cert.CertificateEncodingException;
313 import java.security.cert.CertificateException;
314 import java.text.SimpleDateFormat;
315 import java.util.ArrayList;
316 import java.util.Arrays;
317 import java.util.Collection;
318 import java.util.Collections;
319 import java.util.Comparator;
320 import java.util.Date;
321 import java.util.HashMap;
322 import java.util.HashSet;
323 import java.util.Iterator;
324 import java.util.List;
325 import java.util.Map;
326 import java.util.Objects;
327 import java.util.Set;
328 import java.util.concurrent.CountDownLatch;
329 import java.util.concurrent.Future;
330 import java.util.concurrent.TimeUnit;
331 import java.util.concurrent.atomic.AtomicBoolean;
332 import java.util.concurrent.atomic.AtomicInteger;
333
334 /**
335  * Keep track of all those APKs everywhere.
336  * <p>
337  * Internally there are two important locks:
338  * <ul>
339  * <li>{@link #mPackages} is used to guard all in-memory parsed package details
340  * and other related state. It is a fine-grained lock that should only be held
341  * momentarily, as it's one of the most contended locks in the system.
342  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
343  * operations typically involve heavy lifting of application data on disk. Since
344  * {@code installd} is single-threaded, and it's operations can often be slow,
345  * this lock should never be acquired while already holding {@link #mPackages}.
346  * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
347  * holding {@link #mInstallLock}.
348  * </ul>
349  * Many internal methods rely on the caller to hold the appropriate locks, and
350  * this contract is expressed through method name suffixes:
351  * <ul>
352  * <li>fooLI(): the caller must hold {@link #mInstallLock}
353  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
354  * being modified must be frozen
355  * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
356  * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
357  * </ul>
358  * <p>
359  * Because this class is very central to the platform's security; please run all
360  * CTS and unit tests whenever making modifications:
361  *
362  * <pre>
363  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
364  * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
365  * </pre>
366  */
367 public class PackageManagerService extends IPackageManager.Stub
368         implements PackageSender {
369     static final String TAG = "PackageManager";
370     static final boolean DEBUG_SETTINGS = false;
371     static final boolean DEBUG_PREFERRED = false;
372     static final boolean DEBUG_UPGRADE = false;
373     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
374     private static final boolean DEBUG_BACKUP = false;
375     private static final boolean DEBUG_INSTALL = false;
376     private static final boolean DEBUG_REMOVE = false;
377     private static final boolean DEBUG_BROADCASTS = false;
378     private static final boolean DEBUG_SHOW_INFO = false;
379     private static final boolean DEBUG_PACKAGE_INFO = false;
380     private static final boolean DEBUG_INTENT_MATCHING = false;
381     private static final boolean DEBUG_PACKAGE_SCANNING = false;
382     private static final boolean DEBUG_VERIFY = false;
383     private static final boolean DEBUG_FILTERS = false;
384
385     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
386     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
387     // user, but by default initialize to this.
388     public static final boolean DEBUG_DEXOPT = false;
389
390     private static final boolean DEBUG_ABI_SELECTION = false;
391     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
392     private static final boolean DEBUG_TRIAGED_MISSING = false;
393     private static final boolean DEBUG_APP_DATA = false;
394
395     /** REMOVE. According to Svet, this was only used to reset permissions during development. */
396     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
397
398     private static final boolean HIDE_EPHEMERAL_APIS = false;
399
400     private static final boolean ENABLE_FREE_CACHE_V2 =
401             SystemProperties.getBoolean("fw.free_cache_v2", true);
402
403     private static final int RADIO_UID = Process.PHONE_UID;
404     private static final int LOG_UID = Process.LOG_UID;
405     private static final int NFC_UID = Process.NFC_UID;
406     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
407     private static final int SHELL_UID = Process.SHELL_UID;
408
409     // Cap the size of permission trees that 3rd party apps can define
410     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
411
412     // Suffix used during package installation when copying/moving
413     // package apks to install directory.
414     private static final String INSTALL_PACKAGE_SUFFIX = "-";
415
416     static final int SCAN_NO_DEX = 1<<1;
417     static final int SCAN_FORCE_DEX = 1<<2;
418     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
419     static final int SCAN_NEW_INSTALL = 1<<4;
420     static final int SCAN_UPDATE_TIME = 1<<5;
421     static final int SCAN_BOOTING = 1<<6;
422     static final int SCAN_TRUSTED_OVERLAY = 1<<7;
423     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
424     static final int SCAN_REPLACING = 1<<9;
425     static final int SCAN_REQUIRE_KNOWN = 1<<10;
426     static final int SCAN_MOVE = 1<<11;
427     static final int SCAN_INITIAL = 1<<12;
428     static final int SCAN_CHECK_ONLY = 1<<13;
429     static final int SCAN_DONT_KILL_APP = 1<<14;
430     static final int SCAN_IGNORE_FROZEN = 1<<15;
431     static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
432     static final int SCAN_AS_INSTANT_APP = 1<<17;
433     static final int SCAN_AS_FULL_APP = 1<<18;
434     /** Should not be with the scan flags */
435     static final int FLAGS_REMOVE_CHATTY = 1<<31;
436
437     private static final String STATIC_SHARED_LIB_DELIMITER = "_";
438
439     private static final int[] EMPTY_INT_ARRAY = new int[0];
440
441     /**
442      * Timeout (in milliseconds) after which the watchdog should declare that
443      * our handler thread is wedged.  The usual default for such things is one
444      * minute but we sometimes do very lengthy I/O operations on this thread,
445      * such as installing multi-gigabyte applications, so ours needs to be longer.
446      */
447     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
448
449     /**
450      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
451      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
452      * settings entry if available, otherwise we use the hardcoded default.  If it's been
453      * more than this long since the last fstrim, we force one during the boot sequence.
454      *
455      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
456      * one gets run at the next available charging+idle time.  This final mandatory
457      * no-fstrim check kicks in only of the other scheduling criteria is never met.
458      */
459     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
460
461     /**
462      * Whether verification is enabled by default.
463      */
464     private static final boolean DEFAULT_VERIFY_ENABLE = true;
465
466     /**
467      * The default maximum time to wait for the verification agent to return in
468      * milliseconds.
469      */
470     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
471
472     /**
473      * The default response for package verification timeout.
474      *
475      * This can be either PackageManager.VERIFICATION_ALLOW or
476      * PackageManager.VERIFICATION_REJECT.
477      */
478     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
479
480     static final String PLATFORM_PACKAGE_NAME = "android";
481
482     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
483
484     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
485             DEFAULT_CONTAINER_PACKAGE,
486             "com.android.defcontainer.DefaultContainerService");
487
488     private static final String KILL_APP_REASON_GIDS_CHANGED =
489             "permission grant or revoke changed gids";
490
491     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
492             "permissions revoked";
493
494     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
495
496     private static final String PACKAGE_SCHEME = "package";
497
498     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
499
500     /** Permission grant: not grant the permission. */
501     private static final int GRANT_DENIED = 1;
502
503     /** Permission grant: grant the permission as an install permission. */
504     private static final int GRANT_INSTALL = 2;
505
506     /** Permission grant: grant the permission as a runtime one. */
507     private static final int GRANT_RUNTIME = 3;
508
509     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
510     private static final int GRANT_UPGRADE = 4;
511
512     /** Canonical intent used to identify what counts as a "web browser" app */
513     private static final Intent sBrowserIntent;
514     static {
515         sBrowserIntent = new Intent();
516         sBrowserIntent.setAction(Intent.ACTION_VIEW);
517         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
518         sBrowserIntent.setData(Uri.parse("http:"));
519     }
520
521     /**
522      * The set of all protected actions [i.e. those actions for which a high priority
523      * intent filter is disallowed].
524      */
525     private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
526     static {
527         PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
528         PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
529         PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
530         PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
531     }
532
533     // Compilation reasons.
534     public static final int REASON_FIRST_BOOT = 0;
535     public static final int REASON_BOOT = 1;
536     public static final int REASON_INSTALL = 2;
537     public static final int REASON_BACKGROUND_DEXOPT = 3;
538     public static final int REASON_AB_OTA = 4;
539     public static final int REASON_FORCED_DEXOPT = 5;
540
541     public static final int REASON_LAST = REASON_FORCED_DEXOPT;
542
543     /** All dangerous permission names in the same order as the events in MetricsEvent */
544     private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
545             Manifest.permission.READ_CALENDAR,
546             Manifest.permission.WRITE_CALENDAR,
547             Manifest.permission.CAMERA,
548             Manifest.permission.READ_CONTACTS,
549             Manifest.permission.WRITE_CONTACTS,
550             Manifest.permission.GET_ACCOUNTS,
551             Manifest.permission.ACCESS_FINE_LOCATION,
552             Manifest.permission.ACCESS_COARSE_LOCATION,
553             Manifest.permission.RECORD_AUDIO,
554             Manifest.permission.READ_PHONE_STATE,
555             Manifest.permission.CALL_PHONE,
556             Manifest.permission.READ_CALL_LOG,
557             Manifest.permission.WRITE_CALL_LOG,
558             Manifest.permission.ADD_VOICEMAIL,
559             Manifest.permission.USE_SIP,
560             Manifest.permission.PROCESS_OUTGOING_CALLS,
561             Manifest.permission.READ_CELL_BROADCASTS,
562             Manifest.permission.BODY_SENSORS,
563             Manifest.permission.SEND_SMS,
564             Manifest.permission.RECEIVE_SMS,
565             Manifest.permission.READ_SMS,
566             Manifest.permission.RECEIVE_WAP_PUSH,
567             Manifest.permission.RECEIVE_MMS,
568             Manifest.permission.READ_EXTERNAL_STORAGE,
569             Manifest.permission.WRITE_EXTERNAL_STORAGE,
570             Manifest.permission.READ_PHONE_NUMBERS,
571             Manifest.permission.ANSWER_PHONE_CALLS);
572
573
574     /**
575      * Version number for the package parser cache. Increment this whenever the format or
576      * extent of cached data changes. See {@code PackageParser#setCacheDir}.
577      */
578     private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
579
580     /**
581      * Whether the package parser cache is enabled.
582      */
583     private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
584
585     final ServiceThread mHandlerThread;
586
587     final PackageHandler mHandler;
588
589     private final ProcessLoggingHandler mProcessLoggingHandler;
590
591     /**
592      * Messages for {@link #mHandler} that need to wait for system ready before
593      * being dispatched.
594      */
595     private ArrayList<Message> mPostSystemReadyMessages;
596
597     final int mSdkVersion = Build.VERSION.SDK_INT;
598
599     final Context mContext;
600     final boolean mFactoryTest;
601     final boolean mOnlyCore;
602     final DisplayMetrics mMetrics;
603     final int mDefParseFlags;
604     final String[] mSeparateProcesses;
605     final boolean mIsUpgrade;
606     final boolean mIsPreNUpgrade;
607     final boolean mIsPreNMR1Upgrade;
608
609     // Have we told the Activity Manager to whitelist the default container service by uid yet?
610     @GuardedBy("mPackages")
611     boolean mDefaultContainerWhitelisted = false;
612
613     @GuardedBy("mPackages")
614     private boolean mDexOptDialogShown;
615
616     /** The location for ASEC container files on internal storage. */
617     final String mAsecInternalPath;
618
619     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
620     // LOCK HELD.  Can be called with mInstallLock held.
621     @GuardedBy("mInstallLock")
622     final Installer mInstaller;
623
624     /** Directory where installed third-party apps stored */
625     final File mAppInstallDir;
626
627     /**
628      * Directory to which applications installed internally have their
629      * 32 bit native libraries copied.
630      */
631     private File mAppLib32InstallDir;
632
633     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
634     // apps.
635     final File mDrmAppPrivateInstallDir;
636
637     // ----------------------------------------------------------------
638
639     // Lock for state used when installing and doing other long running
640     // operations.  Methods that must be called with this lock held have
641     // the suffix "LI".
642     final Object mInstallLock = new Object();
643
644     // ----------------------------------------------------------------
645
646     // Keys are String (package name), values are Package.  This also serves
647     // as the lock for the global state.  Methods that must be called with
648     // this lock held have the prefix "LP".
649     @GuardedBy("mPackages")
650     final ArrayMap<String, PackageParser.Package> mPackages =
651             new ArrayMap<String, PackageParser.Package>();
652
653     final ArrayMap<String, Set<String>> mKnownCodebase =
654             new ArrayMap<String, Set<String>>();
655
656     // Keys are isolated uids and values are the uid of the application
657     // that created the isolated proccess.
658     @GuardedBy("mPackages")
659     final SparseIntArray mIsolatedOwners = new SparseIntArray();
660
661     // List of APK paths to load for each user and package. This data is never
662     // persisted by the package manager. Instead, the overlay manager will
663     // ensure the data is up-to-date in runtime.
664     @GuardedBy("mPackages")
665     final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
666         new SparseArray<ArrayMap<String, ArrayList<String>>>();
667
668     /**
669      * Tracks new system packages [received in an OTA] that we expect to
670      * find updated user-installed versions. Keys are package name, values
671      * are package location.
672      */
673     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
674     /**
675      * Tracks high priority intent filters for protected actions. During boot, certain
676      * filter actions are protected and should never be allowed to have a high priority
677      * intent filter for them. However, there is one, and only one exception -- the
678      * setup wizard. It must be able to define a high priority intent filter for these
679      * actions to ensure there are no escapes from the wizard. We need to delay processing
680      * of these during boot as we need to look at all of the system packages in order
681      * to know which component is the setup wizard.
682      */
683     private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
684     /**
685      * Whether or not processing protected filters should be deferred.
686      */
687     private boolean mDeferProtectedFilters = true;
688
689     /**
690      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
691      */
692     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
693     /**
694      * Whether or not system app permissions should be promoted from install to runtime.
695      */
696     boolean mPromoteSystemApps;
697
698     @GuardedBy("mPackages")
699     final Settings mSettings;
700
701     /**
702      * Set of package names that are currently "frozen", which means active
703      * surgery is being done on the code/data for that package. The platform
704      * will refuse to launch frozen packages to avoid race conditions.
705      *
706      * @see PackageFreezer
707      */
708     @GuardedBy("mPackages")
709     final ArraySet<String> mFrozenPackages = new ArraySet<>();
710
711     final ProtectedPackages mProtectedPackages;
712
713     boolean mFirstBoot;
714
715     PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
716
717     // System configuration read by SystemConfig.
718     final int[] mGlobalGids;
719     final SparseArray<ArraySet<String>> mSystemPermissions;
720     @GuardedBy("mAvailableFeatures")
721     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
722
723     // If mac_permissions.xml was found for seinfo labeling.
724     boolean mFoundPolicyFile;
725
726     private final InstantAppRegistry mInstantAppRegistry;
727
728     @GuardedBy("mPackages")
729     int mChangedPackagesSequenceNumber;
730     /**
731      * List of changed [installed, removed or updated] packages.
732      * mapping from user id -> sequence number -> package name
733      */
734     @GuardedBy("mPackages")
735     final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
736     /**
737      * The sequence number of the last change to a package.
738      * mapping from user id -> package name -> sequence number
739      */
740     @GuardedBy("mPackages")
741     final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
742
743     final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
744         @Override public boolean hasFeature(String feature) {
745             return PackageManagerService.this.hasSystemFeature(feature, 0);
746         }
747     };
748
749     public static final class SharedLibraryEntry {
750         public final String path;
751         public final String apk;
752         public final SharedLibraryInfo info;
753
754         SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
755                 String declaringPackageName, int declaringPackageVersionCode) {
756             path = _path;
757             apk = _apk;
758             info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
759                     declaringPackageName, declaringPackageVersionCode), null);
760         }
761     }
762
763     // Currently known shared libraries.
764     final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
765     final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
766             new ArrayMap<>();
767
768     // All available activities, for your resolving pleasure.
769     final ActivityIntentResolver mActivities =
770             new ActivityIntentResolver();
771
772     // All available receivers, for your resolving pleasure.
773     final ActivityIntentResolver mReceivers =
774             new ActivityIntentResolver();
775
776     // All available services, for your resolving pleasure.
777     final ServiceIntentResolver mServices = new ServiceIntentResolver();
778
779     // All available providers, for your resolving pleasure.
780     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
781
782     // Mapping from provider base names (first directory in content URI codePath)
783     // to the provider information.
784     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
785             new ArrayMap<String, PackageParser.Provider>();
786
787     // Mapping from instrumentation class names to info about them.
788     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
789             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
790
791     // Mapping from permission names to info about them.
792     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
793             new ArrayMap<String, PackageParser.PermissionGroup>();
794
795     // Packages whose data we have transfered into another package, thus
796     // should no longer exist.
797     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
798
799     // Broadcast actions that are only available to the system.
800     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
801
802     /** List of packages waiting for verification. */
803     final SparseArray<PackageVerificationState> mPendingVerification
804             = new SparseArray<PackageVerificationState>();
805
806     /** Set of packages associated with each app op permission. */
807     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
808
809     final PackageInstallerService mInstallerService;
810
811     private final PackageDexOptimizer mPackageDexOptimizer;
812     // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
813     // is used by other apps).
814     private final DexManager mDexManager;
815
816     private AtomicInteger mNextMoveId = new AtomicInteger();
817     private final MoveCallbacks mMoveCallbacks;
818
819     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
820
821     // Cache of users who need badging.
822     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
823
824     /** Token for keys in mPendingVerification. */
825     private int mPendingVerificationToken = 0;
826
827     volatile boolean mSystemReady;
828     volatile boolean mSafeMode;
829     volatile boolean mHasSystemUidErrors;
830     private volatile boolean mEphemeralAppsDisabled;
831
832     ApplicationInfo mAndroidApplication;
833     final ActivityInfo mResolveActivity = new ActivityInfo();
834     final ResolveInfo mResolveInfo = new ResolveInfo();
835     ComponentName mResolveComponentName;
836     PackageParser.Package mPlatformPackage;
837     ComponentName mCustomResolverComponentName;
838
839     boolean mResolverReplaced = false;
840
841     private final @Nullable ComponentName mIntentFilterVerifierComponent;
842     private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
843
844     private int mIntentFilterVerificationToken = 0;
845
846     /** The service connection to the ephemeral resolver */
847     final EphemeralResolverConnection mInstantAppResolverConnection;
848     /** Component used to show resolver settings for Instant Apps */
849     final ComponentName mInstantAppResolverSettingsComponent;
850
851     /** Activity used to install instant applications */
852     ActivityInfo mInstantAppInstallerActivity;
853     final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
854
855     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
856             = new SparseArray<IntentFilterVerificationState>();
857
858     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
859
860     // List of packages names to keep cached, even if they are uninstalled for all users
861     private List<String> mKeepUninstalledPackages;
862
863     private UserManagerInternal mUserManagerInternal;
864
865     private DeviceIdleController.LocalService mDeviceIdleController;
866
867     private File mCacheDir;
868
869     private ArraySet<String> mPrivappPermissionsViolations;
870
871     private Future<?> mPrepareAppDataFuture;
872
873     private static class IFVerificationParams {
874         PackageParser.Package pkg;
875         boolean replacing;
876         int userId;
877         int verifierUid;
878
879         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
880                 int _userId, int _verifierUid) {
881             pkg = _pkg;
882             replacing = _replacing;
883             userId = _userId;
884             replacing = _replacing;
885             verifierUid = _verifierUid;
886         }
887     }
888
889     private interface IntentFilterVerifier<T extends IntentFilter> {
890         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
891                                                T filter, String packageName);
892         void startVerifications(int userId);
893         void receiveVerificationResponse(int verificationId);
894     }
895
896     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
897         private Context mContext;
898         private ComponentName mIntentFilterVerifierComponent;
899         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
900
901         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
902             mContext = context;
903             mIntentFilterVerifierComponent = verifierComponent;
904         }
905
906         private String getDefaultScheme() {
907             return IntentFilter.SCHEME_HTTPS;
908         }
909
910         @Override
911         public void startVerifications(int userId) {
912             // Launch verifications requests
913             int count = mCurrentIntentFilterVerifications.size();
914             for (int n=0; n<count; n++) {
915                 int verificationId = mCurrentIntentFilterVerifications.get(n);
916                 final IntentFilterVerificationState ivs =
917                         mIntentFilterVerificationStates.get(verificationId);
918
919                 String packageName = ivs.getPackageName();
920
921                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
922                 final int filterCount = filters.size();
923                 ArraySet<String> domainsSet = new ArraySet<>();
924                 for (int m=0; m<filterCount; m++) {
925                     PackageParser.ActivityIntentInfo filter = filters.get(m);
926                     domainsSet.addAll(filter.getHostsList());
927                 }
928                 synchronized (mPackages) {
929                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
930                             packageName, domainsSet) != null) {
931                         scheduleWriteSettingsLocked();
932                     }
933                 }
934                 sendVerificationRequest(userId, verificationId, ivs);
935             }
936             mCurrentIntentFilterVerifications.clear();
937         }
938
939         private void sendVerificationRequest(int userId, int verificationId,
940                 IntentFilterVerificationState ivs) {
941
942             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
943             verificationIntent.putExtra(
944                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
945                     verificationId);
946             verificationIntent.putExtra(
947                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
948                     getDefaultScheme());
949             verificationIntent.putExtra(
950                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
951                     ivs.getHostsString());
952             verificationIntent.putExtra(
953                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
954                     ivs.getPackageName());
955             verificationIntent.setComponent(mIntentFilterVerifierComponent);
956             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
957
958             UserHandle user = new UserHandle(userId);
959             mContext.sendBroadcastAsUser(verificationIntent, user);
960             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
961                     "Sending IntentFilter verification broadcast");
962         }
963
964         public void receiveVerificationResponse(int verificationId) {
965             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
966
967             final boolean verified = ivs.isVerified();
968
969             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
970             final int count = filters.size();
971             if (DEBUG_DOMAIN_VERIFICATION) {
972                 Slog.i(TAG, "Received verification response " + verificationId
973                         + " for " + count + " filters, verified=" + verified);
974             }
975             for (int n=0; n<count; n++) {
976                 PackageParser.ActivityIntentInfo filter = filters.get(n);
977                 filter.setVerified(verified);
978
979                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
980                         + " verified with result:" + verified + " and hosts:"
981                         + ivs.getHostsString());
982             }
983
984             mIntentFilterVerificationStates.remove(verificationId);
985
986             final String packageName = ivs.getPackageName();
987             IntentFilterVerificationInfo ivi = null;
988
989             synchronized (mPackages) {
990                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
991             }
992             if (ivi == null) {
993                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
994                         + verificationId + " packageName:" + packageName);
995                 return;
996             }
997             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
998                     "Updating IntentFilterVerificationInfo for package " + packageName
999                             +" verificationId:" + verificationId);
1000
1001             synchronized (mPackages) {
1002                 if (verified) {
1003                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1004                 } else {
1005                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1006                 }
1007                 scheduleWriteSettingsLocked();
1008
1009                 final int userId = ivs.getUserId();
1010                 if (userId != UserHandle.USER_ALL) {
1011                     final int userStatus =
1012                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1013
1014                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1015                     boolean needUpdate = false;
1016
1017                     // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1018                     // already been set by the User thru the Disambiguation dialog
1019                     switch (userStatus) {
1020                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1021                             if (verified) {
1022                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1023                             } else {
1024                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1025                             }
1026                             needUpdate = true;
1027                             break;
1028
1029                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1030                             if (verified) {
1031                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1032                                 needUpdate = true;
1033                             }
1034                             break;
1035
1036                         default:
1037                             // Nothing to do
1038                     }
1039
1040                     if (needUpdate) {
1041                         mSettings.updateIntentFilterVerificationStatusLPw(
1042                                 packageName, updatedStatus, userId);
1043                         scheduleWritePackageRestrictionsLocked(userId);
1044                     }
1045                 }
1046             }
1047         }
1048
1049         @Override
1050         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1051                     ActivityIntentInfo filter, String packageName) {
1052             if (!hasValidDomains(filter)) {
1053                 return false;
1054             }
1055             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1056             if (ivs == null) {
1057                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1058                         packageName);
1059             }
1060             if (DEBUG_DOMAIN_VERIFICATION) {
1061                 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1062             }
1063             ivs.addFilter(filter);
1064             return true;
1065         }
1066
1067         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1068                 int userId, int verificationId, String packageName) {
1069             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1070                     verifierUid, userId, packageName);
1071             ivs.setPendingState();
1072             synchronized (mPackages) {
1073                 mIntentFilterVerificationStates.append(verificationId, ivs);
1074                 mCurrentIntentFilterVerifications.add(verificationId);
1075             }
1076             return ivs;
1077         }
1078     }
1079
1080     private static boolean hasValidDomains(ActivityIntentInfo filter) {
1081         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1082                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1083                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1084     }
1085
1086     // Set of pending broadcasts for aggregating enable/disable of components.
1087     static class PendingPackageBroadcasts {
1088         // for each user id, a map of <package name -> components within that package>
1089         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1090
1091         public PendingPackageBroadcasts() {
1092             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1093         }
1094
1095         public ArrayList<String> get(int userId, String packageName) {
1096             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1097             return packages.get(packageName);
1098         }
1099
1100         public void put(int userId, String packageName, ArrayList<String> components) {
1101             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1102             packages.put(packageName, components);
1103         }
1104
1105         public void remove(int userId, String packageName) {
1106             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1107             if (packages != null) {
1108                 packages.remove(packageName);
1109             }
1110         }
1111
1112         public void remove(int userId) {
1113             mUidMap.remove(userId);
1114         }
1115
1116         public int userIdCount() {
1117             return mUidMap.size();
1118         }
1119
1120         public int userIdAt(int n) {
1121             return mUidMap.keyAt(n);
1122         }
1123
1124         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1125             return mUidMap.get(userId);
1126         }
1127
1128         public int size() {
1129             // total number of pending broadcast entries across all userIds
1130             int num = 0;
1131             for (int i = 0; i< mUidMap.size(); i++) {
1132                 num += mUidMap.valueAt(i).size();
1133             }
1134             return num;
1135         }
1136
1137         public void clear() {
1138             mUidMap.clear();
1139         }
1140
1141         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1142             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1143             if (map == null) {
1144                 map = new ArrayMap<String, ArrayList<String>>();
1145                 mUidMap.put(userId, map);
1146             }
1147             return map;
1148         }
1149     }
1150     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1151
1152     // Service Connection to remote media container service to copy
1153     // package uri's from external media onto secure containers
1154     // or internal storage.
1155     private IMediaContainerService mContainerService = null;
1156
1157     static final int SEND_PENDING_BROADCAST = 1;
1158     static final int MCS_BOUND = 3;
1159     static final int END_COPY = 4;
1160     static final int INIT_COPY = 5;
1161     static final int MCS_UNBIND = 6;
1162     static final int START_CLEANING_PACKAGE = 7;
1163     static final int FIND_INSTALL_LOC = 8;
1164     static final int POST_INSTALL = 9;
1165     static final int MCS_RECONNECT = 10;
1166     static final int MCS_GIVE_UP = 11;
1167     static final int UPDATED_MEDIA_STATUS = 12;
1168     static final int WRITE_SETTINGS = 13;
1169     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1170     static final int PACKAGE_VERIFIED = 15;
1171     static final int CHECK_PENDING_VERIFICATION = 16;
1172     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1173     static final int INTENT_FILTER_VERIFIED = 18;
1174     static final int WRITE_PACKAGE_LIST = 19;
1175     static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1176
1177     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1178
1179     // Delay time in millisecs
1180     static final int BROADCAST_DELAY = 10 * 1000;
1181
1182     static UserManagerService sUserManager;
1183
1184     // Stores a list of users whose package restrictions file needs to be updated
1185     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1186
1187     final private DefaultContainerConnection mDefContainerConn =
1188             new DefaultContainerConnection();
1189     class DefaultContainerConnection implements ServiceConnection {
1190         public void onServiceConnected(ComponentName name, IBinder service) {
1191             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1192             final IMediaContainerService imcs = IMediaContainerService.Stub
1193                     .asInterface(Binder.allowBlocking(service));
1194             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1195         }
1196
1197         public void onServiceDisconnected(ComponentName name) {
1198             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1199         }
1200     }
1201
1202     // Recordkeeping of restore-after-install operations that are currently in flight
1203     // between the Package Manager and the Backup Manager
1204     static class PostInstallData {
1205         public InstallArgs args;
1206         public PackageInstalledInfo res;
1207
1208         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1209             args = _a;
1210             res = _r;
1211         }
1212     }
1213
1214     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1215     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1216
1217     // XML tags for backup/restore of various bits of state
1218     private static final String TAG_PREFERRED_BACKUP = "pa";
1219     private static final String TAG_DEFAULT_APPS = "da";
1220     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1221
1222     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1223     private static final String TAG_ALL_GRANTS = "rt-grants";
1224     private static final String TAG_GRANT = "grant";
1225     private static final String ATTR_PACKAGE_NAME = "pkg";
1226
1227     private static final String TAG_PERMISSION = "perm";
1228     private static final String ATTR_PERMISSION_NAME = "name";
1229     private static final String ATTR_IS_GRANTED = "g";
1230     private static final String ATTR_USER_SET = "set";
1231     private static final String ATTR_USER_FIXED = "fixed";
1232     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1233
1234     // System/policy permission grants are not backed up
1235     private static final int SYSTEM_RUNTIME_GRANT_MASK =
1236             FLAG_PERMISSION_POLICY_FIXED
1237             | FLAG_PERMISSION_SYSTEM_FIXED
1238             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1239
1240     // And we back up these user-adjusted states
1241     private static final int USER_RUNTIME_GRANT_MASK =
1242             FLAG_PERMISSION_USER_SET
1243             | FLAG_PERMISSION_USER_FIXED
1244             | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1245
1246     final @Nullable String mRequiredVerifierPackage;
1247     final @NonNull String mRequiredInstallerPackage;
1248     final @NonNull String mRequiredUninstallerPackage;
1249     final @Nullable String mSetupWizardPackage;
1250     final @Nullable String mStorageManagerPackage;
1251     final @NonNull String mServicesSystemSharedLibraryPackageName;
1252     final @NonNull String mSharedSystemSharedLibraryPackageName;
1253
1254     final boolean mPermissionReviewRequired;
1255
1256     private final PackageUsage mPackageUsage = new PackageUsage();
1257     private final CompilerStats mCompilerStats = new CompilerStats();
1258
1259     class PackageHandler extends Handler {
1260         private boolean mBound = false;
1261         final ArrayList<HandlerParams> mPendingInstalls =
1262             new ArrayList<HandlerParams>();
1263
1264         private boolean connectToService() {
1265             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1266                     " DefaultContainerService");
1267             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1268             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1269             if (mContext.bindServiceAsUser(service, mDefContainerConn,
1270                     Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1271                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1272                 mBound = true;
1273                 return true;
1274             }
1275             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1276             return false;
1277         }
1278
1279         private void disconnectService() {
1280             mContainerService = null;
1281             mBound = false;
1282             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1283             mContext.unbindService(mDefContainerConn);
1284             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1285         }
1286
1287         PackageHandler(Looper looper) {
1288             super(looper);
1289         }
1290
1291         public void handleMessage(Message msg) {
1292             try {
1293                 doHandleMessage(msg);
1294             } finally {
1295                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1296             }
1297         }
1298
1299         void doHandleMessage(Message msg) {
1300             switch (msg.what) {
1301                 case INIT_COPY: {
1302                     HandlerParams params = (HandlerParams) msg.obj;
1303                     int idx = mPendingInstalls.size();
1304                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1305                     // If a bind was already initiated we dont really
1306                     // need to do anything. The pending install
1307                     // will be processed later on.
1308                     if (!mBound) {
1309                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1310                                 System.identityHashCode(mHandler));
1311                         // If this is the only one pending we might
1312                         // have to bind to the service again.
1313                         if (!connectToService()) {
1314                             Slog.e(TAG, "Failed to bind to media container service");
1315                             params.serviceError();
1316                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1317                                     System.identityHashCode(mHandler));
1318                             if (params.traceMethod != null) {
1319                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1320                                         params.traceCookie);
1321                             }
1322                             return;
1323                         } else {
1324                             // Once we bind to the service, the first
1325                             // pending request will be processed.
1326                             mPendingInstalls.add(idx, params);
1327                         }
1328                     } else {
1329                         mPendingInstalls.add(idx, params);
1330                         // Already bound to the service. Just make
1331                         // sure we trigger off processing the first request.
1332                         if (idx == 0) {
1333                             mHandler.sendEmptyMessage(MCS_BOUND);
1334                         }
1335                     }
1336                     break;
1337                 }
1338                 case MCS_BOUND: {
1339                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1340                     if (msg.obj != null) {
1341                         mContainerService = (IMediaContainerService) msg.obj;
1342                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1343                                 System.identityHashCode(mHandler));
1344                     }
1345                     if (mContainerService == null) {
1346                         if (!mBound) {
1347                             // Something seriously wrong since we are not bound and we are not
1348                             // waiting for connection. Bail out.
1349                             Slog.e(TAG, "Cannot bind to media container service");
1350                             for (HandlerParams params : mPendingInstalls) {
1351                                 // Indicate service bind error
1352                                 params.serviceError();
1353                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1354                                         System.identityHashCode(params));
1355                                 if (params.traceMethod != null) {
1356                                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1357                                             params.traceMethod, params.traceCookie);
1358                                 }
1359                                 return;
1360                             }
1361                             mPendingInstalls.clear();
1362                         } else {
1363                             Slog.w(TAG, "Waiting to connect to media container service");
1364                         }
1365                     } else if (mPendingInstalls.size() > 0) {
1366                         HandlerParams params = mPendingInstalls.get(0);
1367                         if (params != null) {
1368                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1369                                     System.identityHashCode(params));
1370                             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1371                             if (params.startCopy()) {
1372                                 // We are done...  look for more work or to
1373                                 // go idle.
1374                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
1375                                         "Checking for more work or unbind...");
1376                                 // Delete pending install
1377                                 if (mPendingInstalls.size() > 0) {
1378                                     mPendingInstalls.remove(0);
1379                                 }
1380                                 if (mPendingInstalls.size() == 0) {
1381                                     if (mBound) {
1382                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
1383                                                 "Posting delayed MCS_UNBIND");
1384                                         removeMessages(MCS_UNBIND);
1385                                         Message ubmsg = obtainMessage(MCS_UNBIND);
1386                                         // Unbind after a little delay, to avoid
1387                                         // continual thrashing.
1388                                         sendMessageDelayed(ubmsg, 10000);
1389                                     }
1390                                 } else {
1391                                     // There are more pending requests in queue.
1392                                     // Just post MCS_BOUND message to trigger processing
1393                                     // of next pending install.
1394                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
1395                                             "Posting MCS_BOUND for next work");
1396                                     mHandler.sendEmptyMessage(MCS_BOUND);
1397                                 }
1398                             }
1399                             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1400                         }
1401                     } else {
1402                         // Should never happen ideally.
1403                         Slog.w(TAG, "Empty queue");
1404                     }
1405                     break;
1406                 }
1407                 case MCS_RECONNECT: {
1408                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1409                     if (mPendingInstalls.size() > 0) {
1410                         if (mBound) {
1411                             disconnectService();
1412                         }
1413                         if (!connectToService()) {
1414                             Slog.e(TAG, "Failed to bind to media container service");
1415                             for (HandlerParams params : mPendingInstalls) {
1416                                 // Indicate service bind error
1417                                 params.serviceError();
1418                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1419                                         System.identityHashCode(params));
1420                             }
1421                             mPendingInstalls.clear();
1422                         }
1423                     }
1424                     break;
1425                 }
1426                 case MCS_UNBIND: {
1427                     // If there is no actual work left, then time to unbind.
1428                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1429
1430                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1431                         if (mBound) {
1432                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1433
1434                             disconnectService();
1435                         }
1436                     } else if (mPendingInstalls.size() > 0) {
1437                         // There are more pending requests in queue.
1438                         // Just post MCS_BOUND message to trigger processing
1439                         // of next pending install.
1440                         mHandler.sendEmptyMessage(MCS_BOUND);
1441                     }
1442
1443                     break;
1444                 }
1445                 case MCS_GIVE_UP: {
1446                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1447                     HandlerParams params = mPendingInstalls.remove(0);
1448                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1449                             System.identityHashCode(params));
1450                     break;
1451                 }
1452                 case SEND_PENDING_BROADCAST: {
1453                     String packages[];
1454                     ArrayList<String> components[];
1455                     int size = 0;
1456                     int uids[];
1457                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1458                     synchronized (mPackages) {
1459                         if (mPendingBroadcasts == null) {
1460                             return;
1461                         }
1462                         size = mPendingBroadcasts.size();
1463                         if (size <= 0) {
1464                             // Nothing to be done. Just return
1465                             return;
1466                         }
1467                         packages = new String[size];
1468                         components = new ArrayList[size];
1469                         uids = new int[size];
1470                         int i = 0;  // filling out the above arrays
1471
1472                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1473                             int packageUserId = mPendingBroadcasts.userIdAt(n);
1474                             Iterator<Map.Entry<String, ArrayList<String>>> it
1475                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
1476                                             .entrySet().iterator();
1477                             while (it.hasNext() && i < size) {
1478                                 Map.Entry<String, ArrayList<String>> ent = it.next();
1479                                 packages[i] = ent.getKey();
1480                                 components[i] = ent.getValue();
1481                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1482                                 uids[i] = (ps != null)
1483                                         ? UserHandle.getUid(packageUserId, ps.appId)
1484                                         : -1;
1485                                 i++;
1486                             }
1487                         }
1488                         size = i;
1489                         mPendingBroadcasts.clear();
1490                     }
1491                     // Send broadcasts
1492                     for (int i = 0; i < size; i++) {
1493                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1494                     }
1495                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1496                     break;
1497                 }
1498                 case START_CLEANING_PACKAGE: {
1499                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1500                     final String packageName = (String)msg.obj;
1501                     final int userId = msg.arg1;
1502                     final boolean andCode = msg.arg2 != 0;
1503                     synchronized (mPackages) {
1504                         if (userId == UserHandle.USER_ALL) {
1505                             int[] users = sUserManager.getUserIds();
1506                             for (int user : users) {
1507                                 mSettings.addPackageToCleanLPw(
1508                                         new PackageCleanItem(user, packageName, andCode));
1509                             }
1510                         } else {
1511                             mSettings.addPackageToCleanLPw(
1512                                     new PackageCleanItem(userId, packageName, andCode));
1513                         }
1514                     }
1515                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1516                     startCleaningPackages();
1517                 } break;
1518                 case POST_INSTALL: {
1519                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1520
1521                     PostInstallData data = mRunningInstalls.get(msg.arg1);
1522                     final boolean didRestore = (msg.arg2 != 0);
1523                     mRunningInstalls.delete(msg.arg1);
1524
1525                     if (data != null) {
1526                         InstallArgs args = data.args;
1527                         PackageInstalledInfo parentRes = data.res;
1528
1529                         final boolean grantPermissions = (args.installFlags
1530                                 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1531                         final boolean killApp = (args.installFlags
1532                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1533                         final String[] grantedPermissions = args.installGrantPermissions;
1534
1535                         // Handle the parent package
1536                         handlePackagePostInstall(parentRes, grantPermissions, killApp,
1537                                 grantedPermissions, didRestore, args.installerPackageName,
1538                                 args.observer);
1539
1540                         // Handle the child packages
1541                         final int childCount = (parentRes.addedChildPackages != null)
1542                                 ? parentRes.addedChildPackages.size() : 0;
1543                         for (int i = 0; i < childCount; i++) {
1544                             PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1545                             handlePackagePostInstall(childRes, grantPermissions, killApp,
1546                                     grantedPermissions, false, args.installerPackageName,
1547                                     args.observer);
1548                         }
1549
1550                         // Log tracing if needed
1551                         if (args.traceMethod != null) {
1552                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1553                                     args.traceCookie);
1554                         }
1555                     } else {
1556                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1557                     }
1558
1559                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1560                 } break;
1561                 case UPDATED_MEDIA_STATUS: {
1562                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1563                     boolean reportStatus = msg.arg1 == 1;
1564                     boolean doGc = msg.arg2 == 1;
1565                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1566                     if (doGc) {
1567                         // Force a gc to clear up stale containers.
1568                         Runtime.getRuntime().gc();
1569                     }
1570                     if (msg.obj != null) {
1571                         @SuppressWarnings("unchecked")
1572                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1573                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1574                         // Unload containers
1575                         unloadAllContainers(args);
1576                     }
1577                     if (reportStatus) {
1578                         try {
1579                             if (DEBUG_SD_INSTALL) Log.i(TAG,
1580                                     "Invoking StorageManagerService call back");
1581                             PackageHelper.getStorageManager().finishMediaUpdate();
1582                         } catch (RemoteException e) {
1583                             Log.e(TAG, "StorageManagerService not running?");
1584                         }
1585                     }
1586                 } break;
1587                 case WRITE_SETTINGS: {
1588                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1589                     synchronized (mPackages) {
1590                         removeMessages(WRITE_SETTINGS);
1591                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1592                         mSettings.writeLPr();
1593                         mDirtyUsers.clear();
1594                     }
1595                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1596                 } break;
1597                 case WRITE_PACKAGE_RESTRICTIONS: {
1598                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1599                     synchronized (mPackages) {
1600                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1601                         for (int userId : mDirtyUsers) {
1602                             mSettings.writePackageRestrictionsLPr(userId);
1603                         }
1604                         mDirtyUsers.clear();
1605                     }
1606                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1607                 } break;
1608                 case WRITE_PACKAGE_LIST: {
1609                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1610                     synchronized (mPackages) {
1611                         removeMessages(WRITE_PACKAGE_LIST);
1612                         mSettings.writePackageListLPr(msg.arg1);
1613                     }
1614                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1615                 } break;
1616                 case CHECK_PENDING_VERIFICATION: {
1617                     final int verificationId = msg.arg1;
1618                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1619
1620                     if ((state != null) && !state.timeoutExtended()) {
1621                         final InstallArgs args = state.getInstallArgs();
1622                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1623
1624                         Slog.i(TAG, "Verification timed out for " + originUri);
1625                         mPendingVerification.remove(verificationId);
1626
1627                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1628
1629                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1630                             Slog.i(TAG, "Continuing with installation of " + originUri);
1631                             state.setVerifierResponse(Binder.getCallingUid(),
1632                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1633                             broadcastPackageVerified(verificationId, originUri,
1634                                     PackageManager.VERIFICATION_ALLOW,
1635                                     state.getInstallArgs().getUser());
1636                             try {
1637                                 ret = args.copyApk(mContainerService, true);
1638                             } catch (RemoteException e) {
1639                                 Slog.e(TAG, "Could not contact the ContainerService");
1640                             }
1641                         } else {
1642                             broadcastPackageVerified(verificationId, originUri,
1643                                     PackageManager.VERIFICATION_REJECT,
1644                                     state.getInstallArgs().getUser());
1645                         }
1646
1647                         Trace.asyncTraceEnd(
1648                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1649
1650                         processPendingInstall(args, ret);
1651                         mHandler.sendEmptyMessage(MCS_UNBIND);
1652                     }
1653                     break;
1654                 }
1655                 case PACKAGE_VERIFIED: {
1656                     final int verificationId = msg.arg1;
1657
1658                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1659                     if (state == null) {
1660                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1661                         break;
1662                     }
1663
1664                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1665
1666                     state.setVerifierResponse(response.callerUid, response.code);
1667
1668                     if (state.isVerificationComplete()) {
1669                         mPendingVerification.remove(verificationId);
1670
1671                         final InstallArgs args = state.getInstallArgs();
1672                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1673
1674                         int ret;
1675                         if (state.isInstallAllowed()) {
1676                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1677                             broadcastPackageVerified(verificationId, originUri,
1678                                     response.code, state.getInstallArgs().getUser());
1679                             try {
1680                                 ret = args.copyApk(mContainerService, true);
1681                             } catch (RemoteException e) {
1682                                 Slog.e(TAG, "Could not contact the ContainerService");
1683                             }
1684                         } else {
1685                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1686                         }
1687
1688                         Trace.asyncTraceEnd(
1689                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1690
1691                         processPendingInstall(args, ret);
1692                         mHandler.sendEmptyMessage(MCS_UNBIND);
1693                     }
1694
1695                     break;
1696                 }
1697                 case START_INTENT_FILTER_VERIFICATIONS: {
1698                     IFVerificationParams params = (IFVerificationParams) msg.obj;
1699                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1700                             params.replacing, params.pkg);
1701                     break;
1702                 }
1703                 case INTENT_FILTER_VERIFIED: {
1704                     final int verificationId = msg.arg1;
1705
1706                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1707                             verificationId);
1708                     if (state == null) {
1709                         Slog.w(TAG, "Invalid IntentFilter verification token "
1710                                 + verificationId + " received");
1711                         break;
1712                     }
1713
1714                     final int userId = state.getUserId();
1715
1716                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1717                             "Processing IntentFilter verification with token:"
1718                             + verificationId + " and userId:" + userId);
1719
1720                     final IntentFilterVerificationResponse response =
1721                             (IntentFilterVerificationResponse) msg.obj;
1722
1723                     state.setVerifierResponse(response.callerUid, response.code);
1724
1725                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1726                             "IntentFilter verification with token:" + verificationId
1727                             + " and userId:" + userId
1728                             + " is settings verifier response with response code:"
1729                             + response.code);
1730
1731                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1732                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1733                                 + response.getFailedDomainsString());
1734                     }
1735
1736                     if (state.isVerificationComplete()) {
1737                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1738                     } else {
1739                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1740                                 "IntentFilter verification with token:" + verificationId
1741                                 + " was not said to be complete");
1742                     }
1743
1744                     break;
1745                 }
1746                 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1747                     InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1748                             mInstantAppResolverConnection,
1749                             (InstantAppRequest) msg.obj,
1750                             mInstantAppInstallerActivity,
1751                             mHandler);
1752                 }
1753             }
1754         }
1755     }
1756
1757     private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1758             boolean killApp, String[] grantedPermissions,
1759             boolean launchedForRestore, String installerPackage,
1760             IPackageInstallObserver2 installObserver) {
1761         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1762             // Send the removed broadcasts
1763             if (res.removedInfo != null) {
1764                 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1765             }
1766
1767             // Now that we successfully installed the package, grant runtime
1768             // permissions if requested before broadcasting the install. Also
1769             // for legacy apps in permission review mode we clear the permission
1770             // review flag which is used to emulate runtime permissions for
1771             // legacy apps.
1772             if (grantPermissions) {
1773                 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1774             }
1775
1776             final boolean update = res.removedInfo != null
1777                     && res.removedInfo.removedPackage != null;
1778
1779             // If this is the first time we have child packages for a disabled privileged
1780             // app that had no children, we grant requested runtime permissions to the new
1781             // children if the parent on the system image had them already granted.
1782             if (res.pkg.parentPackage != null) {
1783                 synchronized (mPackages) {
1784                     grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1785                 }
1786             }
1787
1788             synchronized (mPackages) {
1789                 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1790             }
1791
1792             final String packageName = res.pkg.applicationInfo.packageName;
1793
1794             // Determine the set of users who are adding this package for
1795             // the first time vs. those who are seeing an update.
1796             int[] firstUsers = EMPTY_INT_ARRAY;
1797             int[] updateUsers = EMPTY_INT_ARRAY;
1798             final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1799             final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1800             for (int newUser : res.newUsers) {
1801                 if (ps.getInstantApp(newUser)) {
1802                     continue;
1803                 }
1804                 if (allNewUsers) {
1805                     firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1806                     continue;
1807                 }
1808                 boolean isNew = true;
1809                 for (int origUser : res.origUsers) {
1810                     if (origUser == newUser) {
1811                         isNew = false;
1812                         break;
1813                     }
1814                 }
1815                 if (isNew) {
1816                     firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1817                 } else {
1818                     updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1819                 }
1820             }
1821
1822             // Send installed broadcasts if the package is not a static shared lib.
1823             if (res.pkg.staticSharedLibName == null) {
1824                 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1825
1826                 // Send added for users that see the package for the first time
1827                 // sendPackageAddedForNewUsers also deals with system apps
1828                 int appId = UserHandle.getAppId(res.uid);
1829                 boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1830                 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1831
1832                 // Send added for users that don't see the package for the first time
1833                 Bundle extras = new Bundle(1);
1834                 extras.putInt(Intent.EXTRA_UID, res.uid);
1835                 if (update) {
1836                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
1837                 } else {
1838                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
1839                             extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
1840                             null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1841                 }
1842                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1843                         extras, 0 /*flags*/, null /*targetPackage*/,
1844                         null /*finishedReceiver*/, updateUsers);
1845
1846                 // Send replaced for users that don't see the package for the first time
1847                 if (update) {
1848                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1849                             packageName, extras, 0 /*flags*/,
1850                             null /*targetPackage*/, null /*finishedReceiver*/,
1851                             updateUsers);
1852                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1853                             null /*package*/, null /*extras*/, 0 /*flags*/,
1854                             packageName /*targetPackage*/,
1855                             null /*finishedReceiver*/, updateUsers);
1856                 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1857                     // First-install and we did a restore, so we're responsible for the
1858                     // first-launch broadcast.
1859                     if (DEBUG_BACKUP) {
1860                         Slog.i(TAG, "Post-restore of " + packageName
1861                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1862                     }
1863                     sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1864                 }
1865
1866                 // Send broadcast package appeared if forward locked/external for all users
1867                 // treat asec-hosted packages like removable media on upgrade
1868                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1869                     if (DEBUG_INSTALL) {
1870                         Slog.i(TAG, "upgrading pkg " + res.pkg
1871                                 + " is ASEC-hosted -> AVAILABLE");
1872                     }
1873                     final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1874                     ArrayList<String> pkgList = new ArrayList<>(1);
1875                     pkgList.add(packageName);
1876                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1877                 }
1878             }
1879
1880             // Work that needs to happen on first install within each user
1881             if (firstUsers != null && firstUsers.length > 0) {
1882                 synchronized (mPackages) {
1883                     for (int userId : firstUsers) {
1884                         // If this app is a browser and it's newly-installed for some
1885                         // users, clear any default-browser state in those users. The
1886                         // app's nature doesn't depend on the user, so we can just check
1887                         // its browser nature in any user and generalize.
1888                         if (packageIsBrowser(packageName, userId)) {
1889                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1890                         }
1891
1892                         // We may also need to apply pending (restored) runtime
1893                         // permission grants within these users.
1894                         mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1895                     }
1896                 }
1897             }
1898
1899             // Log current value of "unknown sources" setting
1900             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1901                     getUnknownSourcesSettings());
1902
1903             // Force a gc to clear up things
1904             Runtime.getRuntime().gc();
1905
1906             // Remove the replaced package's older resources safely now
1907             // We delete after a gc for applications  on sdcard.
1908             if (res.removedInfo != null && res.removedInfo.args != null) {
1909                 synchronized (mInstallLock) {
1910                     res.removedInfo.args.doPostDeleteLI(true);
1911                 }
1912             }
1913
1914             // Notify DexManager that the package was installed for new users.
1915             // The updated users should already be indexed and the package code paths
1916             // should not change.
1917             // Don't notify the manager for ephemeral apps as they are not expected to
1918             // survive long enough to benefit of background optimizations.
1919             for (int userId : firstUsers) {
1920                 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
1921                 // There's a race currently where some install events may interleave with an uninstall.
1922                 // This can lead to package info being null (b/36642664).
1923                 if (info != null) {
1924                     mDexManager.notifyPackageInstalled(info, userId);
1925                 }
1926             }
1927         }
1928
1929         // If someone is watching installs - notify them
1930         if (installObserver != null) {
1931             try {
1932                 Bundle extras = extrasForInstallResult(res);
1933                 installObserver.onPackageInstalled(res.name, res.returnCode,
1934                         res.returnMsg, extras);
1935             } catch (RemoteException e) {
1936                 Slog.i(TAG, "Observer no longer exists.");
1937             }
1938         }
1939     }
1940
1941     private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1942             PackageParser.Package pkg) {
1943         if (pkg.parentPackage == null) {
1944             return;
1945         }
1946         if (pkg.requestedPermissions == null) {
1947             return;
1948         }
1949         final PackageSetting disabledSysParentPs = mSettings
1950                 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1951         if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1952                 || !disabledSysParentPs.isPrivileged()
1953                 || (disabledSysParentPs.childPackageNames != null
1954                         && !disabledSysParentPs.childPackageNames.isEmpty())) {
1955             return;
1956         }
1957         final int[] allUserIds = sUserManager.getUserIds();
1958         final int permCount = pkg.requestedPermissions.size();
1959         for (int i = 0; i < permCount; i++) {
1960             String permission = pkg.requestedPermissions.get(i);
1961             BasePermission bp = mSettings.mPermissions.get(permission);
1962             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1963                 continue;
1964             }
1965             for (int userId : allUserIds) {
1966                 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1967                         permission, userId)) {
1968                     grantRuntimePermission(pkg.packageName, permission, userId);
1969                 }
1970             }
1971         }
1972     }
1973
1974     private StorageEventListener mStorageListener = new StorageEventListener() {
1975         @Override
1976         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1977             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1978                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1979                     final String volumeUuid = vol.getFsUuid();
1980
1981                     // Clean up any users or apps that were removed or recreated
1982                     // while this volume was missing
1983                     sUserManager.reconcileUsers(volumeUuid);
1984                     reconcileApps(volumeUuid);
1985
1986                     // Clean up any install sessions that expired or were
1987                     // cancelled while this volume was missing
1988                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
1989
1990                     loadPrivatePackages(vol);
1991
1992                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1993                     unloadPrivatePackages(vol);
1994                 }
1995             }
1996
1997             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1998                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1999                     updateExternalMediaStatus(true, false);
2000                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2001                     updateExternalMediaStatus(false, false);
2002                 }
2003             }
2004         }
2005
2006         @Override
2007         public void onVolumeForgotten(String fsUuid) {
2008             if (TextUtils.isEmpty(fsUuid)) {
2009                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2010                 return;
2011             }
2012
2013             // Remove any apps installed on the forgotten volume
2014             synchronized (mPackages) {
2015                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2016                 for (PackageSetting ps : packages) {
2017                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2018                     deletePackageVersioned(new VersionedPackage(ps.name,
2019                             PackageManager.VERSION_CODE_HIGHEST),
2020                             new LegacyPackageDeleteObserver(null).getBinder(),
2021                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2022                     // Try very hard to release any references to this package
2023                     // so we don't risk the system server being killed due to
2024                     // open FDs
2025                     AttributeCache.instance().removePackage(ps.name);
2026                 }
2027
2028                 mSettings.onVolumeForgotten(fsUuid);
2029                 mSettings.writeLPr();
2030             }
2031         }
2032     };
2033
2034     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2035             String[] grantedPermissions) {
2036         for (int userId : userIds) {
2037             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2038         }
2039     }
2040
2041     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2042             String[] grantedPermissions) {
2043         SettingBase sb = (SettingBase) pkg.mExtras;
2044         if (sb == null) {
2045             return;
2046         }
2047
2048         PermissionsState permissionsState = sb.getPermissionsState();
2049
2050         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2051                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2052
2053         final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2054                 >= Build.VERSION_CODES.M;
2055
2056         final boolean instantApp = isInstantApp(pkg.packageName, userId);
2057
2058         for (String permission : pkg.requestedPermissions) {
2059             final BasePermission bp;
2060             synchronized (mPackages) {
2061                 bp = mSettings.mPermissions.get(permission);
2062             }
2063             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2064                     && (!instantApp || bp.isInstant())
2065                     && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2066                     && (grantedPermissions == null
2067                            || ArrayUtils.contains(grantedPermissions, permission))) {
2068                 final int flags = permissionsState.getPermissionFlags(permission, userId);
2069                 if (supportsRuntimePermissions) {
2070                     // Installer cannot change immutable permissions.
2071                     if ((flags & immutableFlags) == 0) {
2072                         grantRuntimePermission(pkg.packageName, permission, userId);
2073                     }
2074                 } else if (mPermissionReviewRequired) {
2075                     // In permission review mode we clear the review flag when we
2076                     // are asked to install the app with all permissions granted.
2077                     if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2078                         updatePermissionFlags(permission, pkg.packageName,
2079                                 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2080                     }
2081                 }
2082             }
2083         }
2084     }
2085
2086     Bundle extrasForInstallResult(PackageInstalledInfo res) {
2087         Bundle extras = null;
2088         switch (res.returnCode) {
2089             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2090                 extras = new Bundle();
2091                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2092                         res.origPermission);
2093                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2094                         res.origPackage);
2095                 break;
2096             }
2097             case PackageManager.INSTALL_SUCCEEDED: {
2098                 extras = new Bundle();
2099                 extras.putBoolean(Intent.EXTRA_REPLACING,
2100                         res.removedInfo != null && res.removedInfo.removedPackage != null);
2101                 break;
2102             }
2103         }
2104         return extras;
2105     }
2106
2107     void scheduleWriteSettingsLocked() {
2108         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2109             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2110         }
2111     }
2112
2113     void scheduleWritePackageListLocked(int userId) {
2114         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2115             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2116             msg.arg1 = userId;
2117             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2118         }
2119     }
2120
2121     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2122         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2123         scheduleWritePackageRestrictionsLocked(userId);
2124     }
2125
2126     void scheduleWritePackageRestrictionsLocked(int userId) {
2127         final int[] userIds = (userId == UserHandle.USER_ALL)
2128                 ? sUserManager.getUserIds() : new int[]{userId};
2129         for (int nextUserId : userIds) {
2130             if (!sUserManager.exists(nextUserId)) return;
2131             mDirtyUsers.add(nextUserId);
2132             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2133                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2134             }
2135         }
2136     }
2137
2138     public static PackageManagerService main(Context context, Installer installer,
2139             boolean factoryTest, boolean onlyCore) {
2140         // Self-check for initial settings.
2141         PackageManagerServiceCompilerMapping.checkProperties();
2142
2143         PackageManagerService m = new PackageManagerService(context, installer,
2144                 factoryTest, onlyCore);
2145         m.enableSystemUserPackages();
2146         ServiceManager.addService("package", m);
2147         return m;
2148     }
2149
2150     private void enableSystemUserPackages() {
2151         if (!UserManager.isSplitSystemUser()) {
2152             return;
2153         }
2154         // For system user, enable apps based on the following conditions:
2155         // - app is whitelisted or belong to one of these groups:
2156         //   -- system app which has no launcher icons
2157         //   -- system app which has INTERACT_ACROSS_USERS permission
2158         //   -- system IME app
2159         // - app is not in the blacklist
2160         AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2161         Set<String> enableApps = new ArraySet<>();
2162         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2163                 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2164                 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2165         ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2166         enableApps.addAll(wlApps);
2167         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2168                 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2169         ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2170         enableApps.removeAll(blApps);
2171         Log.i(TAG, "Applications installed for system user: " + enableApps);
2172         List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2173                 UserHandle.SYSTEM);
2174         final int allAppsSize = allAps.size();
2175         synchronized (mPackages) {
2176             for (int i = 0; i < allAppsSize; i++) {
2177                 String pName = allAps.get(i);
2178                 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2179                 // Should not happen, but we shouldn't be failing if it does
2180                 if (pkgSetting == null) {
2181                     continue;
2182                 }
2183                 boolean install = enableApps.contains(pName);
2184                 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2185                     Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2186                             + " for system user");
2187                     pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2188                 }
2189             }
2190             scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2191         }
2192     }
2193
2194     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2195         DisplayManager displayManager = (DisplayManager) context.getSystemService(
2196                 Context.DISPLAY_SERVICE);
2197         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2198     }
2199
2200     /**
2201      * Requests that files preopted on a secondary system partition be copied to the data partition
2202      * if possible.  Note that the actual copying of the files is accomplished by init for security
2203      * reasons. This simply requests that the copy takes place and awaits confirmation of its
2204      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2205      */
2206     private static void requestCopyPreoptedFiles() {
2207         final int WAIT_TIME_MS = 100;
2208         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2209         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2210             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2211             // We will wait for up to 100 seconds.
2212             final long timeStart = SystemClock.uptimeMillis();
2213             final long timeEnd = timeStart + 100 * 1000;
2214             long timeNow = timeStart;
2215             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2216                 try {
2217                     Thread.sleep(WAIT_TIME_MS);
2218                 } catch (InterruptedException e) {
2219                     // Do nothing
2220                 }
2221                 timeNow = SystemClock.uptimeMillis();
2222                 if (timeNow > timeEnd) {
2223                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2224                     Slog.wtf(TAG, "cppreopt did not finish!");
2225                     break;
2226                 }
2227             }
2228
2229             Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2230         }
2231     }
2232
2233     public PackageManagerService(Context context, Installer installer,
2234             boolean factoryTest, boolean onlyCore) {
2235         LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2236         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2237         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2238                 SystemClock.uptimeMillis());
2239
2240         if (mSdkVersion <= 0) {
2241             Slog.w(TAG, "**** ro.build.version.sdk not set!");
2242         }
2243
2244         mContext = context;
2245
2246         mPermissionReviewRequired = context.getResources().getBoolean(
2247                 R.bool.config_permissionReviewRequired);
2248
2249         mFactoryTest = factoryTest;
2250         mOnlyCore = onlyCore;
2251         mMetrics = new DisplayMetrics();
2252         mSettings = new Settings(mPackages);
2253         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2254                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2255         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2256                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2257         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2258                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2259         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2260                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2261         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2262                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2263         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2264                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2265
2266         String separateProcesses = SystemProperties.get("debug.separate_processes");
2267         if (separateProcesses != null && separateProcesses.length() > 0) {
2268             if ("*".equals(separateProcesses)) {
2269                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2270                 mSeparateProcesses = null;
2271                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2272             } else {
2273                 mDefParseFlags = 0;
2274                 mSeparateProcesses = separateProcesses.split(",");
2275                 Slog.w(TAG, "Running with debug.separate_processes: "
2276                         + separateProcesses);
2277             }
2278         } else {
2279             mDefParseFlags = 0;
2280             mSeparateProcesses = null;
2281         }
2282
2283         mInstaller = installer;
2284         mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2285                 "*dexopt*");
2286         mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2287         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2288
2289         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2290                 FgThread.get().getLooper());
2291
2292         getDefaultDisplayMetrics(context, mMetrics);
2293
2294         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2295         SystemConfig systemConfig = SystemConfig.getInstance();
2296         mGlobalGids = systemConfig.getGlobalGids();
2297         mSystemPermissions = systemConfig.getSystemPermissions();
2298         mAvailableFeatures = systemConfig.getAvailableFeatures();
2299         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2300
2301         mProtectedPackages = new ProtectedPackages(mContext);
2302
2303         synchronized (mInstallLock) {
2304         // writer
2305         synchronized (mPackages) {
2306             mHandlerThread = new ServiceThread(TAG,
2307                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2308             mHandlerThread.start();
2309             mHandler = new PackageHandler(mHandlerThread.getLooper());
2310             mProcessLoggingHandler = new ProcessLoggingHandler();
2311             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2312
2313             mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2314             mInstantAppRegistry = new InstantAppRegistry(this);
2315
2316             File dataDir = Environment.getDataDirectory();
2317             mAppInstallDir = new File(dataDir, "app");
2318             mAppLib32InstallDir = new File(dataDir, "app-lib");
2319             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2320             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2321             sUserManager = new UserManagerService(context, this,
2322                     new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2323
2324             // Propagate permission configuration in to package manager.
2325             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2326                     = systemConfig.getPermissions();
2327             for (int i=0; i<permConfig.size(); i++) {
2328                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2329                 BasePermission bp = mSettings.mPermissions.get(perm.name);
2330                 if (bp == null) {
2331                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2332                     mSettings.mPermissions.put(perm.name, bp);
2333                 }
2334                 if (perm.gids != null) {
2335                     bp.setGids(perm.gids, perm.perUser);
2336                 }
2337             }
2338
2339             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2340             final int builtInLibCount = libConfig.size();
2341             for (int i = 0; i < builtInLibCount; i++) {
2342                 String name = libConfig.keyAt(i);
2343                 String path = libConfig.valueAt(i);
2344                 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2345                         SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2346             }
2347
2348             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2349
2350             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2351             mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2352             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2353
2354             // Clean up orphaned packages for which the code path doesn't exist
2355             // and they are an update to a system app - caused by bug/32321269
2356             final int packageSettingCount = mSettings.mPackages.size();
2357             for (int i = packageSettingCount - 1; i >= 0; i--) {
2358                 PackageSetting ps = mSettings.mPackages.valueAt(i);
2359                 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2360                         && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2361                     mSettings.mPackages.removeAt(i);
2362                     mSettings.enableSystemPackageLPw(ps.name);
2363                 }
2364             }
2365
2366             if (mFirstBoot) {
2367                 requestCopyPreoptedFiles();
2368             }
2369
2370             String customResolverActivity = Resources.getSystem().getString(
2371                     R.string.config_customResolverActivity);
2372             if (TextUtils.isEmpty(customResolverActivity)) {
2373                 customResolverActivity = null;
2374             } else {
2375                 mCustomResolverComponentName = ComponentName.unflattenFromString(
2376                         customResolverActivity);
2377             }
2378
2379             long startTime = SystemClock.uptimeMillis();
2380
2381             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2382                     startTime);
2383
2384             final String bootClassPath = System.getenv("BOOTCLASSPATH");
2385             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2386
2387             if (bootClassPath == null) {
2388                 Slog.w(TAG, "No BOOTCLASSPATH found!");
2389             }
2390
2391             if (systemServerClassPath == null) {
2392                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2393             }
2394
2395             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2396
2397             final VersionInfo ver = mSettings.getInternalVersion();
2398             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2399             if (mIsUpgrade) {
2400                 logCriticalInfo(Log.INFO,
2401                         "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2402             }
2403
2404             // when upgrading from pre-M, promote system app permissions from install to runtime
2405             mPromoteSystemApps =
2406                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2407
2408             // When upgrading from pre-N, we need to handle package extraction like first boot,
2409             // as there is no profiling data available.
2410             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2411
2412             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2413
2414             // save off the names of pre-existing system packages prior to scanning; we don't
2415             // want to automatically grant runtime permissions for new system apps
2416             if (mPromoteSystemApps) {
2417                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2418                 while (pkgSettingIter.hasNext()) {
2419                     PackageSetting ps = pkgSettingIter.next();
2420                     if (isSystemApp(ps)) {
2421                         mExistingSystemPackages.add(ps.name);
2422                     }
2423                 }
2424             }
2425
2426             mCacheDir = preparePackageParserCache(mIsUpgrade);
2427
2428             // Set flag to monitor and not change apk file paths when
2429             // scanning install directories.
2430             int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2431
2432             if (mIsUpgrade || mFirstBoot) {
2433                 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2434             }
2435
2436             // Collect vendor overlay packages. (Do this before scanning any apps.)
2437             // For security and version matching reason, only consider
2438             // overlay packages if they reside in the right directory.
2439             scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2440                     | PackageParser.PARSE_IS_SYSTEM
2441                     | PackageParser.PARSE_IS_SYSTEM_DIR
2442                     | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2443
2444             // Find base frameworks (resource packages without code).
2445             scanDirTracedLI(frameworkDir, mDefParseFlags
2446                     | PackageParser.PARSE_IS_SYSTEM
2447                     | PackageParser.PARSE_IS_SYSTEM_DIR
2448                     | PackageParser.PARSE_IS_PRIVILEGED,
2449                     scanFlags | SCAN_NO_DEX, 0);
2450
2451             // Collected privileged system packages.
2452             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2453             scanDirTracedLI(privilegedAppDir, mDefParseFlags
2454                     | PackageParser.PARSE_IS_SYSTEM
2455                     | PackageParser.PARSE_IS_SYSTEM_DIR
2456                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2457
2458             // Collect ordinary system packages.
2459             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2460             scanDirTracedLI(systemAppDir, mDefParseFlags
2461                     | PackageParser.PARSE_IS_SYSTEM
2462                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2463
2464             // Collect all vendor packages.
2465             File vendorAppDir = new File("/vendor/app");
2466             try {
2467                 vendorAppDir = vendorAppDir.getCanonicalFile();
2468             } catch (IOException e) {
2469                 // failed to look up canonical path, continue with original one
2470             }
2471             scanDirTracedLI(vendorAppDir, mDefParseFlags
2472                     | PackageParser.PARSE_IS_SYSTEM
2473                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2474
2475             // Collect all OEM packages.
2476             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2477             scanDirTracedLI(oemAppDir, mDefParseFlags
2478                     | PackageParser.PARSE_IS_SYSTEM
2479                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2480
2481             // Prune any system packages that no longer exist.
2482             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2483             if (!mOnlyCore) {
2484                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2485                 while (psit.hasNext()) {
2486                     PackageSetting ps = psit.next();
2487
2488                     /*
2489                      * If this is not a system app, it can't be a
2490                      * disable system app.
2491                      */
2492                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2493                         continue;
2494                     }
2495
2496                     /*
2497                      * If the package is scanned, it's not erased.
2498                      */
2499                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2500                     if (scannedPkg != null) {
2501                         /*
2502                          * If the system app is both scanned and in the
2503                          * disabled packages list, then it must have been
2504                          * added via OTA. Remove it from the currently
2505                          * scanned package so the previously user-installed
2506                          * application can be scanned.
2507                          */
2508                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2509                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2510                                     + ps.name + "; removing system app.  Last known codePath="
2511                                     + ps.codePathString + ", installStatus=" + ps.installStatus
2512                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2513                                     + scannedPkg.mVersionCode);
2514                             removePackageLI(scannedPkg, true);
2515                             mExpectingBetter.put(ps.name, ps.codePath);
2516                         }
2517
2518                         continue;
2519                     }
2520
2521                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2522                         psit.remove();
2523                         logCriticalInfo(Log.WARN, "System package " + ps.name
2524                                 + " no longer exists; it's data will be wiped");
2525                         // Actual deletion of code and data will be handled by later
2526                         // reconciliation step
2527                     } else {
2528                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2529                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2530                             possiblyDeletedUpdatedSystemApps.add(ps.name);
2531                         }
2532                     }
2533                 }
2534             }
2535
2536             //look for any incomplete package installations
2537             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2538             for (int i = 0; i < deletePkgsList.size(); i++) {
2539                 // Actual deletion of code and data will be handled by later
2540                 // reconciliation step
2541                 final String packageName = deletePkgsList.get(i).name;
2542                 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2543                 synchronized (mPackages) {
2544                     mSettings.removePackageLPw(packageName);
2545                 }
2546             }
2547
2548             //delete tmp files
2549             deleteTempPackageFiles();
2550
2551             // Remove any shared userIDs that have no associated packages
2552             mSettings.pruneSharedUsersLPw();
2553
2554             if (!mOnlyCore) {
2555                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2556                         SystemClock.uptimeMillis());
2557                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2558
2559                 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2560                         | PackageParser.PARSE_FORWARD_LOCK,
2561                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2562
2563                 /**
2564                  * Remove disable package settings for any updated system
2565                  * apps that were removed via an OTA. If they're not a
2566                  * previously-updated app, remove them completely.
2567                  * Otherwise, just revoke their system-level permissions.
2568                  */
2569                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2570                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2571                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2572
2573                     String msg;
2574                     if (deletedPkg == null) {
2575                         msg = "Updated system package " + deletedAppName
2576                                 + " no longer exists; it's data will be wiped";
2577                         // Actual deletion of code and data will be handled by later
2578                         // reconciliation step
2579                     } else {
2580                         msg = "Updated system app + " + deletedAppName
2581                                 + " no longer present; removing system privileges for "
2582                                 + deletedAppName;
2583
2584                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2585
2586                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2587                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2588                     }
2589                     logCriticalInfo(Log.WARN, msg);
2590                 }
2591
2592                 /**
2593                  * Make sure all system apps that we expected to appear on
2594                  * the userdata partition actually showed up. If they never
2595                  * appeared, crawl back and revive the system version.
2596                  */
2597                 for (int i = 0; i < mExpectingBetter.size(); i++) {
2598                     final String packageName = mExpectingBetter.keyAt(i);
2599                     if (!mPackages.containsKey(packageName)) {
2600                         final File scanFile = mExpectingBetter.valueAt(i);
2601
2602                         logCriticalInfo(Log.WARN, "Expected better " + packageName
2603                                 + " but never showed up; reverting to system");
2604
2605                         int reparseFlags = mDefParseFlags;
2606                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
2607                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2608                                     | PackageParser.PARSE_IS_SYSTEM_DIR
2609                                     | PackageParser.PARSE_IS_PRIVILEGED;
2610                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
2611                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2612                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2613                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2614                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2615                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2616                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
2617                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2618                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2619                         } else {
2620                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2621                             continue;
2622                         }
2623
2624                         mSettings.enableSystemPackageLPw(packageName);
2625
2626                         try {
2627                             scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2628                         } catch (PackageManagerException e) {
2629                             Slog.e(TAG, "Failed to parse original system package: "
2630                                     + e.getMessage());
2631                         }
2632                     }
2633                 }
2634             }
2635             mExpectingBetter.clear();
2636
2637             // Resolve the storage manager.
2638             mStorageManagerPackage = getStorageManagerPackageName();
2639
2640             // Resolve protected action filters. Only the setup wizard is allowed to
2641             // have a high priority filter for these actions.
2642             mSetupWizardPackage = getSetupWizardPackageName();
2643             if (mProtectedFilters.size() > 0) {
2644                 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2645                     Slog.i(TAG, "No setup wizard;"
2646                         + " All protected intents capped to priority 0");
2647                 }
2648                 for (ActivityIntentInfo filter : mProtectedFilters) {
2649                     if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2650                         if (DEBUG_FILTERS) {
2651                             Slog.i(TAG, "Found setup wizard;"
2652                                 + " allow priority " + filter.getPriority() + ";"
2653                                 + " package: " + filter.activity.info.packageName
2654                                 + " activity: " + filter.activity.className
2655                                 + " priority: " + filter.getPriority());
2656                         }
2657                         // skip setup wizard; allow it to keep the high priority filter
2658                         continue;
2659                     }
2660                     Slog.w(TAG, "Protected action; cap priority to 0;"
2661                             + " package: " + filter.activity.info.packageName
2662                             + " activity: " + filter.activity.className
2663                             + " origPrio: " + filter.getPriority());
2664                     filter.setPriority(0);
2665                 }
2666             }
2667             mDeferProtectedFilters = false;
2668             mProtectedFilters.clear();
2669
2670             // Now that we know all of the shared libraries, update all clients to have
2671             // the correct library paths.
2672             updateAllSharedLibrariesLPw(null);
2673
2674             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2675                 // NOTE: We ignore potential failures here during a system scan (like
2676                 // the rest of the commands above) because there's precious little we
2677                 // can do about it. A settings error is reported, though.
2678                 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2679             }
2680
2681             // Now that we know all the packages we are keeping,
2682             // read and update their last usage times.
2683             mPackageUsage.read(mPackages);
2684             mCompilerStats.read();
2685
2686             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2687                     SystemClock.uptimeMillis());
2688             Slog.i(TAG, "Time to scan packages: "
2689                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
2690                     + " seconds");
2691
2692             // If the platform SDK has changed since the last time we booted,
2693             // we need to re-grant app permission to catch any new ones that
2694             // appear.  This is really a hack, and means that apps can in some
2695             // cases get permissions that the user didn't initially explicitly
2696             // allow...  it would be nice to have some better way to handle
2697             // this situation.
2698             int updateFlags = UPDATE_PERMISSIONS_ALL;
2699             if (ver.sdkVersion != mSdkVersion) {
2700                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2701                         + mSdkVersion + "; regranting permissions for internal storage");
2702                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2703             }
2704             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2705             ver.sdkVersion = mSdkVersion;
2706
2707             // If this is the first boot or an update from pre-M, and it is a normal
2708             // boot, then we need to initialize the default preferred apps across
2709             // all defined users.
2710             if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2711                 for (UserInfo user : sUserManager.getUsers(true)) {
2712                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2713                     applyFactoryDefaultBrowserLPw(user.id);
2714                     primeDomainVerificationsLPw(user.id);
2715                 }
2716             }
2717
2718             // Prepare storage for system user really early during boot,
2719             // since core system apps like SettingsProvider and SystemUI
2720             // can't wait for user to start
2721             final int storageFlags;
2722             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2723                 storageFlags = StorageManager.FLAG_STORAGE_DE;
2724             } else {
2725                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2726             }
2727             List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2728                     UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2729                     true /* onlyCoreApps */);
2730             mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2731                 BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2732                         Trace.TRACE_TAG_PACKAGE_MANAGER);
2733                 traceLog.traceBegin("AppDataFixup");
2734                 try {
2735                     mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2736                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2737                 } catch (InstallerException e) {
2738                     Slog.w(TAG, "Trouble fixing GIDs", e);
2739                 }
2740                 traceLog.traceEnd();
2741
2742                 traceLog.traceBegin("AppDataPrepare");
2743                 if (deferPackages == null || deferPackages.isEmpty()) {
2744                     return;
2745                 }
2746                 int count = 0;
2747                 for (String pkgName : deferPackages) {
2748                     PackageParser.Package pkg = null;
2749                     synchronized (mPackages) {
2750                         PackageSetting ps = mSettings.getPackageLPr(pkgName);
2751                         if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2752                             pkg = ps.pkg;
2753                         }
2754                     }
2755                     if (pkg != null) {
2756                         synchronized (mInstallLock) {
2757                             prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2758                                     true /* maybeMigrateAppData */);
2759                         }
2760                         count++;
2761                     }
2762                 }
2763                 traceLog.traceEnd();
2764                 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2765             }, "prepareAppData");
2766
2767             // If this is first boot after an OTA, and a normal boot, then
2768             // we need to clear code cache directories.
2769             // Note that we do *not* clear the application profiles. These remain valid
2770             // across OTAs and are used to drive profile verification (post OTA) and
2771             // profile compilation (without waiting to collect a fresh set of profiles).
2772             if (mIsUpgrade && !onlyCore) {
2773                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2774                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2775                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
2776                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2777                         // No apps are running this early, so no need to freeze
2778                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2779                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2780                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2781                     }
2782                 }
2783                 ver.fingerprint = Build.FINGERPRINT;
2784             }
2785
2786             checkDefaultBrowser();
2787
2788             // clear only after permissions and other defaults have been updated
2789             mExistingSystemPackages.clear();
2790             mPromoteSystemApps = false;
2791
2792             // All the changes are done during package scanning.
2793             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2794
2795             // can downgrade to reader
2796             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2797             mSettings.writeLPr();
2798             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2799
2800             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2801                     SystemClock.uptimeMillis());
2802
2803             if (!mOnlyCore) {
2804                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2805                 mRequiredInstallerPackage = getRequiredInstallerLPr();
2806                 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2807                 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2808                 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2809                         mIntentFilterVerifierComponent);
2810                 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2811                         PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2812                         SharedLibraryInfo.VERSION_UNDEFINED);
2813                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2814                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2815                         SharedLibraryInfo.VERSION_UNDEFINED);
2816             } else {
2817                 mRequiredVerifierPackage = null;
2818                 mRequiredInstallerPackage = null;
2819                 mRequiredUninstallerPackage = null;
2820                 mIntentFilterVerifierComponent = null;
2821                 mIntentFilterVerifier = null;
2822                 mServicesSystemSharedLibraryPackageName = null;
2823                 mSharedSystemSharedLibraryPackageName = null;
2824             }
2825
2826             mInstallerService = new PackageInstallerService(context, this);
2827             final Pair<ComponentName, String> instantAppResolverComponent =
2828                     getInstantAppResolverLPr();
2829             if (instantAppResolverComponent != null) {
2830                 if (DEBUG_EPHEMERAL) {
2831                     Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2832                 }
2833                 mInstantAppResolverConnection = new EphemeralResolverConnection(
2834                         mContext, instantAppResolverComponent.first,
2835                         instantAppResolverComponent.second);
2836                 mInstantAppResolverSettingsComponent =
2837                         getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2838             } else {
2839                 mInstantAppResolverConnection = null;
2840                 mInstantAppResolverSettingsComponent = null;
2841             }
2842             updateInstantAppInstallerLocked(null);
2843
2844             // Read and update the usage of dex files.
2845             // Do this at the end of PM init so that all the packages have their
2846             // data directory reconciled.
2847             // At this point we know the code paths of the packages, so we can validate
2848             // the disk file and build the internal cache.
2849             // The usage file is expected to be small so loading and verifying it
2850             // should take a fairly small time compare to the other activities (e.g. package
2851             // scanning).
2852             final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2853             final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2854             for (int userId : currentUserIds) {
2855                 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2856             }
2857             mDexManager.load(userPackages);
2858         } // synchronized (mPackages)
2859         } // synchronized (mInstallLock)
2860
2861         // Now after opening every single application zip, make sure they
2862         // are all flushed.  Not really needed, but keeps things nice and
2863         // tidy.
2864         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2865         Runtime.getRuntime().gc();
2866         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2867
2868         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2869         FallbackCategoryProvider.loadFallbacks();
2870         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2871
2872         // The initial scanning above does many calls into installd while
2873         // holding the mPackages lock, but we're mostly interested in yelling
2874         // once we have a booted system.
2875         mInstaller.setWarnIfHeld(mPackages);
2876
2877         // Expose private service for system components to use.
2878         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2879         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2880     }
2881
2882     private void updateInstantAppInstallerLocked(String modifiedPackage) {
2883         // we're only interested in updating the installer appliction when 1) it's not
2884         // already set or 2) the modified package is the installer
2885         if (mInstantAppInstallerActivity != null
2886                 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
2887                         .equals(modifiedPackage)) {
2888             return;
2889         }
2890         setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
2891     }
2892
2893     private static File preparePackageParserCache(boolean isUpgrade) {
2894         if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
2895             return null;
2896         }
2897
2898         // Disable package parsing on eng builds to allow for faster incremental development.
2899         if ("eng".equals(Build.TYPE)) {
2900             return null;
2901         }
2902
2903         if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
2904             Slog.i(TAG, "Disabling package parser cache due to system property.");
2905             return null;
2906         }
2907
2908         // The base directory for the package parser cache lives under /data/system/.
2909         final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
2910                 "package_cache");
2911         if (cacheBaseDir == null) {
2912             return null;
2913         }
2914
2915         // If this is a system upgrade scenario, delete the contents of the package cache dir.
2916         // This also serves to "GC" unused entries when the package cache version changes (which
2917         // can only happen during upgrades).
2918         if (isUpgrade) {
2919             FileUtils.deleteContents(cacheBaseDir);
2920         }
2921
2922
2923         // Return the versioned package cache directory. This is something like
2924         // "/data/system/package_cache/1"
2925         File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2926
2927         // The following is a workaround to aid development on non-numbered userdebug
2928         // builds or cases where "adb sync" is used on userdebug builds. If we detect that
2929         // the system partition is newer.
2930         //
2931         // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
2932         // that starts with "eng." to signify that this is an engineering build and not
2933         // destined for release.
2934         if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
2935             Slog.w(TAG, "Wiping cache directory because the system partition changed.");
2936
2937             // Heuristic: If the /system directory has been modified recently due to an "adb sync"
2938             // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
2939             // in general and should not be used for production changes. In this specific case,
2940             // we know that they will work.
2941             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2942             if (cacheDir.lastModified() < frameworkDir.lastModified()) {
2943                 FileUtils.deleteContents(cacheBaseDir);
2944                 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2945             }
2946         }
2947
2948         return cacheDir;
2949     }
2950
2951     @Override
2952     public boolean isFirstBoot() {
2953         return mFirstBoot;
2954     }
2955
2956     @Override
2957     public boolean isOnlyCoreApps() {
2958         return mOnlyCore;
2959     }
2960
2961     @Override
2962     public boolean isUpgrade() {
2963         return mIsUpgrade;
2964     }
2965
2966     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2967         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2968
2969         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2970                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2971                 UserHandle.USER_SYSTEM);
2972         if (matches.size() == 1) {
2973             return matches.get(0).getComponentInfo().packageName;
2974         } else if (matches.size() == 0) {
2975             Log.e(TAG, "There should probably be a verifier, but, none were found");
2976             return null;
2977         }
2978         throw new RuntimeException("There must be exactly one verifier; found " + matches);
2979     }
2980
2981     private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
2982         synchronized (mPackages) {
2983             SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
2984             if (libraryEntry == null) {
2985                 throw new IllegalStateException("Missing required shared library:" + name);
2986             }
2987             return libraryEntry.apk;
2988         }
2989     }
2990
2991     private @NonNull String getRequiredInstallerLPr() {
2992         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2993         intent.addCategory(Intent.CATEGORY_DEFAULT);
2994         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2995
2996         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2997                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2998                 UserHandle.USER_SYSTEM);
2999         if (matches.size() == 1) {
3000             ResolveInfo resolveInfo = matches.get(0);
3001             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3002                 throw new RuntimeException("The installer must be a privileged app");
3003             }
3004             return matches.get(0).getComponentInfo().packageName;
3005         } else {
3006             throw new RuntimeException("There must be exactly one installer; found " + matches);
3007         }
3008     }
3009
3010     private @NonNull String getRequiredUninstallerLPr() {
3011         final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3012         intent.addCategory(Intent.CATEGORY_DEFAULT);
3013         intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3014
3015         final ResolveInfo resolveInfo = resolveIntent(intent, null,
3016                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3017                 UserHandle.USER_SYSTEM);
3018         if (resolveInfo == null ||
3019                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3020             throw new RuntimeException("There must be exactly one uninstaller; found "
3021                     + resolveInfo);
3022         }
3023         return resolveInfo.getComponentInfo().packageName;
3024     }
3025
3026     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3027         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3028
3029         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3030                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3031                 UserHandle.USER_SYSTEM);
3032         ResolveInfo best = null;
3033         final int N = matches.size();
3034         for (int i = 0; i < N; i++) {
3035             final ResolveInfo cur = matches.get(i);
3036             final String packageName = cur.getComponentInfo().packageName;
3037             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3038                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3039                 continue;
3040             }
3041
3042             if (best == null || cur.priority > best.priority) {
3043                 best = cur;
3044             }
3045         }
3046
3047         if (best != null) {
3048             return best.getComponentInfo().getComponentName();
3049         } else {
3050             throw new RuntimeException("There must be at least one intent filter verifier");
3051         }
3052     }
3053
3054     private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3055         final String[] packageArray =
3056                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3057         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3058             if (DEBUG_EPHEMERAL) {
3059                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3060             }
3061             return null;
3062         }
3063
3064         final int callingUid = Binder.getCallingUid();
3065         final int resolveFlags =
3066                 MATCH_DIRECT_BOOT_AWARE
3067                 | MATCH_DIRECT_BOOT_UNAWARE
3068                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3069         String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3070         final Intent resolverIntent = new Intent(actionName);
3071         List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3072                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3073         // temporarily look for the old action
3074         if (resolvers.size() == 0) {
3075             if (DEBUG_EPHEMERAL) {
3076                 Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3077             }
3078             actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3079             resolverIntent.setAction(actionName);
3080             resolvers = queryIntentServicesInternal(resolverIntent, null,
3081                     resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3082         }
3083         final int N = resolvers.size();
3084         if (N == 0) {
3085             if (DEBUG_EPHEMERAL) {
3086                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3087             }
3088             return null;
3089         }
3090
3091         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3092         for (int i = 0; i < N; i++) {
3093             final ResolveInfo info = resolvers.get(i);
3094
3095             if (info.serviceInfo == null) {
3096                 continue;
3097             }
3098
3099             final String packageName = info.serviceInfo.packageName;
3100             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3101                 if (DEBUG_EPHEMERAL) {
3102                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3103                             + " pkg: " + packageName + ", info:" + info);
3104                 }
3105                 continue;
3106             }
3107
3108             if (DEBUG_EPHEMERAL) {
3109                 Slog.v(TAG, "Ephemeral resolver found;"
3110                         + " pkg: " + packageName + ", info:" + info);
3111             }
3112             return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3113         }
3114         if (DEBUG_EPHEMERAL) {
3115             Slog.v(TAG, "Ephemeral resolver NOT found");
3116         }
3117         return null;
3118     }
3119
3120     private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3121         final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3122         intent.addCategory(Intent.CATEGORY_DEFAULT);
3123         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3124
3125         final int resolveFlags =
3126                 MATCH_DIRECT_BOOT_AWARE
3127                 | MATCH_DIRECT_BOOT_UNAWARE
3128                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3129         List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3130                 resolveFlags, UserHandle.USER_SYSTEM);
3131         // temporarily look for the old action
3132         if (matches.isEmpty()) {
3133             if (DEBUG_EPHEMERAL) {
3134                 Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3135             }
3136             intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3137             matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3138                     resolveFlags, UserHandle.USER_SYSTEM);
3139         }
3140         Iterator<ResolveInfo> iter = matches.iterator();
3141         while (iter.hasNext()) {
3142             final ResolveInfo rInfo = iter.next();
3143             final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3144             if (ps != null) {
3145                 final PermissionsState permissionsState = ps.getPermissionsState();
3146                 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3147                     continue;
3148                 }
3149             }
3150             iter.remove();
3151         }
3152         if (matches.size() == 0) {
3153             return null;
3154         } else if (matches.size() == 1) {
3155             return (ActivityInfo) matches.get(0).getComponentInfo();
3156         } else {
3157             throw new RuntimeException(
3158                     "There must be at most one ephemeral installer; found " + matches);
3159         }
3160     }
3161
3162     private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3163             @NonNull ComponentName resolver) {
3164         final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3165                 .addCategory(Intent.CATEGORY_DEFAULT)
3166                 .setPackage(resolver.getPackageName());
3167         final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3168         List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3169                 UserHandle.USER_SYSTEM);
3170         // temporarily look for the old action
3171         if (matches.isEmpty()) {
3172             if (DEBUG_EPHEMERAL) {
3173                 Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3174             }
3175             intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3176             matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3177                     UserHandle.USER_SYSTEM);
3178         }
3179         if (matches.isEmpty()) {
3180             return null;
3181         }
3182         return matches.get(0).getComponentInfo().getComponentName();
3183     }
3184
3185     private void primeDomainVerificationsLPw(int userId) {
3186         if (DEBUG_DOMAIN_VERIFICATION) {
3187             Slog.d(TAG, "Priming domain verifications in user " + userId);
3188         }
3189
3190         SystemConfig systemConfig = SystemConfig.getInstance();
3191         ArraySet<String> packages = systemConfig.getLinkedApps();
3192
3193         for (String packageName : packages) {
3194             PackageParser.Package pkg = mPackages.get(packageName);
3195             if (pkg != null) {
3196                 if (!pkg.isSystemApp()) {
3197                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3198                     continue;
3199                 }
3200
3201                 ArraySet<String> domains = null;
3202                 for (PackageParser.Activity a : pkg.activities) {
3203                     for (ActivityIntentInfo filter : a.intents) {
3204                         if (hasValidDomains(filter)) {
3205                             if (domains == null) {
3206                                 domains = new ArraySet<String>();
3207                             }
3208                             domains.addAll(filter.getHostsList());
3209                         }
3210                     }
3211                 }
3212
3213                 if (domains != null && domains.size() > 0) {
3214                     if (DEBUG_DOMAIN_VERIFICATION) {
3215                         Slog.v(TAG, "      + " + packageName);
3216                     }
3217                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3218                     // state w.r.t. the formal app-linkage "no verification attempted" state;
3219                     // and then 'always' in the per-user state actually used for intent resolution.
3220                     final IntentFilterVerificationInfo ivi;
3221                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3222                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3223                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3224                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3225                 } else {
3226                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3227                             + "' does not handle web links");
3228                 }
3229             } else {
3230                 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3231             }
3232         }
3233
3234         scheduleWritePackageRestrictionsLocked(userId);
3235         scheduleWriteSettingsLocked();
3236     }
3237
3238     private void applyFactoryDefaultBrowserLPw(int userId) {
3239         // The default browser app's package name is stored in a string resource,
3240         // with a product-specific overlay used for vendor customization.
3241         String browserPkg = mContext.getResources().getString(
3242                 com.android.internal.R.string.default_browser);
3243         if (!TextUtils.isEmpty(browserPkg)) {
3244             // non-empty string => required to be a known package
3245             PackageSetting ps = mSettings.mPackages.get(browserPkg);
3246             if (ps == null) {
3247                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3248                 browserPkg = null;
3249             } else {
3250                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3251             }
3252         }
3253
3254         // Nothing valid explicitly set? Make the factory-installed browser the explicit
3255         // default.  If there's more than one, just leave everything alone.
3256         if (browserPkg == null) {
3257             calculateDefaultBrowserLPw(userId);
3258         }
3259     }
3260
3261     private void calculateDefaultBrowserLPw(int userId) {
3262         List<String> allBrowsers = resolveAllBrowserApps(userId);
3263         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3264         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3265     }
3266
3267     private List<String> resolveAllBrowserApps(int userId) {
3268         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3269         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3270                 PackageManager.MATCH_ALL, userId);
3271
3272         final int count = list.size();
3273         List<String> result = new ArrayList<String>(count);
3274         for (int i=0; i<count; i++) {
3275             ResolveInfo info = list.get(i);
3276             if (info.activityInfo == null
3277                     || !info.handleAllWebDataURI
3278                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3279                     || result.contains(info.activityInfo.packageName)) {
3280                 continue;
3281             }
3282             result.add(info.activityInfo.packageName);
3283         }
3284
3285         return result;
3286     }
3287
3288     private boolean packageIsBrowser(String packageName, int userId) {
3289         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3290                 PackageManager.MATCH_ALL, userId);
3291         final int N = list.size();
3292         for (int i = 0; i < N; i++) {
3293             ResolveInfo info = list.get(i);
3294             if (packageName.equals(info.activityInfo.packageName)) {
3295                 return true;
3296             }
3297         }
3298         return false;
3299     }
3300
3301     private void checkDefaultBrowser() {
3302         final int myUserId = UserHandle.myUserId();
3303         final String packageName = getDefaultBrowserPackageName(myUserId);
3304         if (packageName != null) {
3305             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3306             if (info == null) {
3307                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3308                 synchronized (mPackages) {
3309                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3310                 }
3311             }
3312         }
3313     }
3314
3315     @Override
3316     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3317             throws RemoteException {
3318         try {
3319             return super.onTransact(code, data, reply, flags);
3320         } catch (RuntimeException e) {
3321             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3322                 Slog.wtf(TAG, "Package Manager Crash", e);
3323             }
3324             throw e;
3325         }
3326     }
3327
3328     static int[] appendInts(int[] cur, int[] add) {
3329         if (add == null) return cur;
3330         if (cur == null) return add;
3331         final int N = add.length;
3332         for (int i=0; i<N; i++) {
3333             cur = appendInt(cur, add[i]);
3334         }
3335         return cur;
3336     }
3337
3338     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3339         if (!sUserManager.exists(userId)) return null;
3340         if (ps == null) {
3341             return null;
3342         }
3343         final PackageParser.Package p = ps.pkg;
3344         if (p == null) {
3345             return null;
3346         }
3347         // Filter out ephemeral app metadata:
3348         //   * The system/shell/root can see metadata for any app
3349         //   * An installed app can see metadata for 1) other installed apps
3350         //     and 2) ephemeral apps that have explicitly interacted with it
3351         //   * Ephemeral apps can only see their own data and exposed installed apps
3352         //   * Holding a signature permission allows seeing instant apps
3353         final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
3354         if (callingAppId != Process.SYSTEM_UID
3355                 && callingAppId != Process.SHELL_UID
3356                 && callingAppId != Process.ROOT_UID
3357                 && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
3358                         Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
3359             final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
3360             if (instantAppPackageName != null) {
3361                 // ephemeral apps can only get information on themselves or
3362                 // installed apps that are exposed.
3363                 if (!instantAppPackageName.equals(p.packageName)
3364                         && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3365                     return null;
3366                 }
3367             } else {
3368                 if (ps.getInstantApp(userId)) {
3369                     // only get access to the ephemeral app if we've been granted access
3370                     if (!mInstantAppRegistry.isInstantAccessGranted(
3371                             userId, callingAppId, ps.appId)) {
3372                         return null;
3373                     }
3374                 }
3375             }
3376         }
3377
3378         final PermissionsState permissionsState = ps.getPermissionsState();
3379
3380         // Compute GIDs only if requested
3381         final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3382                 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3383         // Compute granted permissions only if package has requested permissions
3384         final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3385                 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3386         final PackageUserState state = ps.readUserState(userId);
3387
3388         if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3389                 && ps.isSystem()) {
3390             flags |= MATCH_ANY_USER;
3391         }
3392
3393         PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3394                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3395
3396         if (packageInfo == null) {
3397             return null;
3398         }
3399
3400         rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3401
3402         packageInfo.packageName = packageInfo.applicationInfo.packageName =
3403                 resolveExternalPackageNameLPr(p);
3404
3405         return packageInfo;
3406     }
3407
3408     @Override
3409     public void checkPackageStartable(String packageName, int userId) {
3410         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3411
3412         synchronized (mPackages) {
3413             final PackageSetting ps = mSettings.mPackages.get(packageName);
3414             if (ps == null) {
3415                 throw new SecurityException("Package " + packageName + " was not found!");
3416             }
3417
3418             if (!ps.getInstalled(userId)) {
3419                 throw new SecurityException(
3420                         "Package " + packageName + " was not installed for user " + userId + "!");
3421             }
3422
3423             if (mSafeMode && !ps.isSystem()) {
3424                 throw new SecurityException("Package " + packageName + " not a system app!");
3425             }
3426
3427             if (mFrozenPackages.contains(packageName)) {
3428                 throw new SecurityException("Package " + packageName + " is currently frozen!");
3429             }
3430
3431             if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3432                     || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3433                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3434             }
3435         }
3436     }
3437
3438     @Override
3439     public boolean isPackageAvailable(String packageName, int userId) {
3440         if (!sUserManager.exists(userId)) return false;
3441         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3442                 false /* requireFullPermission */, false /* checkShell */, "is package available");
3443         synchronized (mPackages) {
3444             PackageParser.Package p = mPackages.get(packageName);
3445             if (p != null) {
3446                 final PackageSetting ps = (PackageSetting) p.mExtras;
3447                 if (ps != null) {
3448                     final PackageUserState state = ps.readUserState(userId);
3449                     if (state != null) {
3450                         return PackageParser.isAvailable(state);
3451                     }
3452                 }
3453             }
3454         }
3455         return false;
3456     }
3457
3458     @Override
3459     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3460         return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3461                 flags, userId);
3462     }
3463
3464     @Override
3465     public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3466             int flags, int userId) {
3467         return getPackageInfoInternal(versionedPackage.getPackageName(),
3468                 // TODO: We will change version code to long, so in the new API it is long
3469                 (int) versionedPackage.getVersionCode(), flags, userId);
3470     }
3471
3472     private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3473             int flags, int userId) {
3474         if (!sUserManager.exists(userId)) return null;
3475         flags = updateFlagsForPackage(flags, userId, packageName);
3476         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3477                 false /* requireFullPermission */, false /* checkShell */, "get package info");
3478
3479         // reader
3480         synchronized (mPackages) {
3481             // Normalize package name to handle renamed packages and static libs
3482             packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3483
3484             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3485             if (matchFactoryOnly) {
3486                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3487                 if (ps != null) {
3488                     if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3489                         return null;
3490                     }
3491                     return generatePackageInfo(ps, flags, userId);
3492                 }
3493             }
3494
3495             PackageParser.Package p = mPackages.get(packageName);
3496             if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3497                 return null;
3498             }
3499             if (DEBUG_PACKAGE_INFO)
3500                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3501             if (p != null) {
3502                 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
3503                         Binder.getCallingUid(), userId)) {
3504                     return null;
3505                 }
3506                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3507             }
3508             if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3509                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3510                 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3511                     return null;
3512                 }
3513                 return generatePackageInfo(ps, flags, userId);
3514             }
3515         }
3516         return null;
3517     }
3518
3519
3520     private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) {
3521         // System/shell/root get to see all static libs
3522         final int appId = UserHandle.getAppId(uid);
3523         if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3524                 || appId == Process.ROOT_UID) {
3525             return false;
3526         }
3527
3528         // No package means no static lib as it is always on internal storage
3529         if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3530             return false;
3531         }
3532
3533         final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3534                 ps.pkg.staticSharedLibVersion);
3535         if (libEntry == null) {
3536             return false;
3537         }
3538
3539         final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3540         final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3541         if (uidPackageNames == null) {
3542             return true;
3543         }
3544
3545         for (String uidPackageName : uidPackageNames) {
3546             if (ps.name.equals(uidPackageName)) {
3547                 return false;
3548             }
3549             PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3550             if (uidPs != null) {
3551                 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3552                         libEntry.info.getName());
3553                 if (index < 0) {
3554                     continue;
3555                 }
3556                 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3557                     return false;
3558                 }
3559             }
3560         }
3561         return true;
3562     }
3563
3564     @Override
3565     public String[] currentToCanonicalPackageNames(String[] names) {
3566         String[] out = new String[names.length];
3567         // reader
3568         synchronized (mPackages) {
3569             for (int i=names.length-1; i>=0; i--) {
3570                 PackageSetting ps = mSettings.mPackages.get(names[i]);
3571                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3572             }
3573         }
3574         return out;
3575     }
3576
3577     @Override
3578     public String[] canonicalToCurrentPackageNames(String[] names) {
3579         String[] out = new String[names.length];
3580         // reader
3581         synchronized (mPackages) {
3582             for (int i=names.length-1; i>=0; i--) {
3583                 String cur = mSettings.getRenamedPackageLPr(names[i]);
3584                 out[i] = cur != null ? cur : names[i];
3585             }
3586         }
3587         return out;
3588     }
3589
3590     @Override
3591     public int getPackageUid(String packageName, int flags, int userId) {
3592         if (!sUserManager.exists(userId)) return -1;
3593         flags = updateFlagsForPackage(flags, userId, packageName);
3594         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3595                 false /* requireFullPermission */, false /* checkShell */, "get package uid");
3596
3597         // reader
3598         synchronized (mPackages) {
3599             final PackageParser.Package p = mPackages.get(packageName);
3600             if (p != null && p.isMatch(flags)) {
3601                 return UserHandle.getUid(userId, p.applicationInfo.uid);
3602             }
3603             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3604                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3605                 if (ps != null && ps.isMatch(flags)) {
3606                     return UserHandle.getUid(userId, ps.appId);
3607                 }
3608             }
3609         }
3610
3611         return -1;
3612     }
3613
3614     @Override
3615     public int[] getPackageGids(String packageName, int flags, int userId) {
3616         if (!sUserManager.exists(userId)) return null;
3617         flags = updateFlagsForPackage(flags, userId, packageName);
3618         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3619                 false /* requireFullPermission */, false /* checkShell */,
3620                 "getPackageGids");
3621
3622         // reader
3623         synchronized (mPackages) {
3624             final PackageParser.Package p = mPackages.get(packageName);
3625             if (p != null && p.isMatch(flags)) {
3626                 PackageSetting ps = (PackageSetting) p.mExtras;
3627                 // TODO: Shouldn't this be checking for package installed state for userId and
3628                 // return null?
3629                 return ps.getPermissionsState().computeGids(userId);
3630             }
3631             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3632                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3633                 if (ps != null && ps.isMatch(flags)) {
3634                     return ps.getPermissionsState().computeGids(userId);
3635                 }
3636             }
3637         }
3638
3639         return null;
3640     }
3641
3642     static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3643         if (bp.perm != null) {
3644             return PackageParser.generatePermissionInfo(bp.perm, flags);
3645         }
3646         PermissionInfo pi = new PermissionInfo();
3647         pi.name = bp.name;
3648         pi.packageName = bp.sourcePackage;
3649         pi.nonLocalizedLabel = bp.name;
3650         pi.protectionLevel = bp.protectionLevel;
3651         return pi;
3652     }
3653
3654     @Override
3655     public PermissionInfo getPermissionInfo(String name, int flags) {
3656         // reader
3657         synchronized (mPackages) {
3658             final BasePermission p = mSettings.mPermissions.get(name);
3659             if (p != null) {
3660                 return generatePermissionInfo(p, flags);
3661             }
3662             return null;
3663         }
3664     }
3665
3666     @Override
3667     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3668             int flags) {
3669         // reader
3670         synchronized (mPackages) {
3671             if (group != null && !mPermissionGroups.containsKey(group)) {
3672                 // This is thrown as NameNotFoundException
3673                 return null;
3674             }
3675
3676             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3677             for (BasePermission p : mSettings.mPermissions.values()) {
3678                 if (group == null) {
3679                     if (p.perm == null || p.perm.info.group == null) {
3680                         out.add(generatePermissionInfo(p, flags));
3681                     }
3682                 } else {
3683                     if (p.perm != null && group.equals(p.perm.info.group)) {
3684                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3685                     }
3686                 }
3687             }
3688             return new ParceledListSlice<>(out);
3689         }
3690     }
3691
3692     @Override
3693     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3694         // reader
3695         synchronized (mPackages) {
3696             return PackageParser.generatePermissionGroupInfo(
3697                     mPermissionGroups.get(name), flags);
3698         }
3699     }
3700
3701     @Override
3702     public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3703         // reader
3704         synchronized (mPackages) {
3705             final int N = mPermissionGroups.size();
3706             ArrayList<PermissionGroupInfo> out
3707                     = new ArrayList<PermissionGroupInfo>(N);
3708             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3709                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3710             }
3711             return new ParceledListSlice<>(out);
3712         }
3713     }
3714
3715     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3716             int uid, int userId) {
3717         if (!sUserManager.exists(userId)) return null;
3718         PackageSetting ps = mSettings.mPackages.get(packageName);
3719         if (ps != null) {
3720             if (filterSharedLibPackageLPr(ps, uid, userId)) {
3721                 return null;
3722             }
3723             if (ps.pkg == null) {
3724                 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3725                 if (pInfo != null) {
3726                     return pInfo.applicationInfo;
3727                 }
3728                 return null;
3729             }
3730             ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3731                     ps.readUserState(userId), userId);
3732             if (ai != null) {
3733                 rebaseEnabledOverlays(ai, userId);
3734                 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3735             }
3736             return ai;
3737         }
3738         return null;
3739     }
3740
3741     @Override
3742     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3743         if (!sUserManager.exists(userId)) return null;
3744         flags = updateFlagsForApplication(flags, userId, packageName);
3745         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3746                 false /* requireFullPermission */, false /* checkShell */, "get application info");
3747
3748         // writer
3749         synchronized (mPackages) {
3750             // Normalize package name to handle renamed packages and static libs
3751             packageName = resolveInternalPackageNameLPr(packageName,
3752                     PackageManager.VERSION_CODE_HIGHEST);
3753
3754             PackageParser.Package p = mPackages.get(packageName);
3755             if (DEBUG_PACKAGE_INFO) Log.v(
3756                     TAG, "getApplicationInfo " + packageName
3757                     + ": " + p);
3758             if (p != null) {
3759                 PackageSetting ps = mSettings.mPackages.get(packageName);
3760                 if (ps == null) return null;
3761                 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3762                     return null;
3763                 }
3764                 // Note: isEnabledLP() does not apply here - always return info
3765                 ApplicationInfo ai = PackageParser.generateApplicationInfo(
3766                         p, flags, ps.readUserState(userId), userId);
3767                 if (ai != null) {
3768                     rebaseEnabledOverlays(ai, userId);
3769                     ai.packageName = resolveExternalPackageNameLPr(p);
3770                 }
3771                 return ai;
3772             }
3773             if ("android".equals(packageName)||"system".equals(packageName)) {
3774                 return mAndroidApplication;
3775             }
3776             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3777                 // Already generates the external package name
3778                 return generateApplicationInfoFromSettingsLPw(packageName,
3779                         Binder.getCallingUid(), flags, userId);
3780             }
3781         }
3782         return null;
3783     }
3784
3785     private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
3786         List<String> paths = new ArrayList<>();
3787         ArrayMap<String, ArrayList<String>> userSpecificOverlays =
3788             mEnabledOverlayPaths.get(userId);
3789         if (userSpecificOverlays != null) {
3790             if (!"android".equals(ai.packageName)) {
3791                 ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
3792                 if (frameworkOverlays != null) {
3793                     paths.addAll(frameworkOverlays);
3794                 }
3795             }
3796
3797             ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
3798             if (appOverlays != null) {
3799                 paths.addAll(appOverlays);
3800             }
3801         }
3802         ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
3803     }
3804
3805     private String normalizePackageNameLPr(String packageName) {
3806         String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3807         return normalizedPackageName != null ? normalizedPackageName : packageName;
3808     }
3809
3810     @Override
3811     public void deletePreloadsFileCache() {
3812         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
3813             throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
3814         }
3815         File dir = Environment.getDataPreloadsFileCacheDirectory();
3816         Slog.i(TAG, "Deleting preloaded file cache " + dir);
3817         FileUtils.deleteContents(dir);
3818     }
3819
3820     @Override
3821     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3822             final IPackageDataObserver observer) {
3823         mContext.enforceCallingOrSelfPermission(
3824                 android.Manifest.permission.CLEAR_APP_CACHE, null);
3825         mHandler.post(() -> {
3826             boolean success = false;
3827             try {
3828                 freeStorage(volumeUuid, freeStorageSize, 0);
3829                 success = true;
3830             } catch (IOException e) {
3831                 Slog.w(TAG, e);
3832             }
3833             if (observer != null) {
3834                 try {
3835                     observer.onRemoveCompleted(null, success);
3836                 } catch (RemoteException e) {
3837                     Slog.w(TAG, e);
3838                 }
3839             }
3840         });
3841     }
3842
3843     @Override
3844     public void freeStorage(final String volumeUuid, final long freeStorageSize,
3845             final IntentSender pi) {
3846         mContext.enforceCallingOrSelfPermission(
3847                 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
3848         mHandler.post(() -> {
3849             boolean success = false;
3850             try {
3851                 freeStorage(volumeUuid, freeStorageSize, 0);
3852                 success = true;
3853             } catch (IOException e) {
3854                 Slog.w(TAG, e);
3855             }
3856             if (pi != null) {
3857                 try {
3858                     pi.sendIntent(null, success ? 1 : 0, null, null, null);
3859                 } catch (SendIntentException e) {
3860                     Slog.w(TAG, e);
3861                 }
3862             }
3863         });
3864     }
3865
3866     /**
3867      * Blocking call to clear various types of cached data across the system
3868      * until the requested bytes are available.
3869      */
3870     public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
3871         final StorageManager storage = mContext.getSystemService(StorageManager.class);
3872         final File file = storage.findPathForUuid(volumeUuid);
3873         if (file.getUsableSpace() >= bytes) return;
3874
3875         if (ENABLE_FREE_CACHE_V2) {
3876             final boolean aggressive = (storageFlags
3877                     & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
3878             final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
3879                     volumeUuid);
3880
3881             // 1. Pre-flight to determine if we have any chance to succeed
3882             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
3883             if (internalVolume && (aggressive || SystemProperties
3884                     .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
3885                 deletePreloadsFileCache();
3886                 if (file.getUsableSpace() >= bytes) return;
3887             }
3888
3889             // 3. Consider parsed APK data (aggressive only)
3890             if (internalVolume && aggressive) {
3891                 FileUtils.deleteContents(mCacheDir);
3892                 if (file.getUsableSpace() >= bytes) return;
3893             }
3894
3895             // 4. Consider cached app data (above quotas)
3896             try {
3897                 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
3898             } catch (InstallerException ignored) {
3899             }
3900             if (file.getUsableSpace() >= bytes) return;
3901
3902             // 5. Consider shared libraries with refcount=0 and age>2h
3903             // 6. Consider dexopt output (aggressive only)
3904             // 7. Consider ephemeral apps not used in last week
3905
3906             // 8. Consider cached app data (below quotas)
3907             try {
3908                 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
3909                         | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
3910             } catch (InstallerException ignored) {
3911             }
3912             if (file.getUsableSpace() >= bytes) return;
3913
3914             // 9. Consider DropBox entries
3915             // 10. Consider ephemeral cookies
3916
3917         } else {
3918             try {
3919                 mInstaller.freeCache(volumeUuid, bytes, 0);
3920             } catch (InstallerException ignored) {
3921             }
3922             if (file.getUsableSpace() >= bytes) return;
3923         }
3924
3925         throw new IOException("Failed to free " + bytes + " on storage device at " + file);
3926     }
3927
3928     /**
3929      * Update given flags based on encryption status of current user.
3930      */
3931     private int updateFlags(int flags, int userId) {
3932         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3933                 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3934             // Caller expressed an explicit opinion about what encryption
3935             // aware/unaware components they want to see, so fall through and
3936             // give them what they want
3937         } else {
3938             // Caller expressed no opinion, so match based on user state
3939             if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3940                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3941             } else {
3942                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3943             }
3944         }
3945         return flags;
3946     }
3947
3948     private UserManagerInternal getUserManagerInternal() {
3949         if (mUserManagerInternal == null) {
3950             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3951         }
3952         return mUserManagerInternal;
3953     }
3954
3955     private DeviceIdleController.LocalService getDeviceIdleController() {
3956         if (mDeviceIdleController == null) {
3957             mDeviceIdleController =
3958                     LocalServices.getService(DeviceIdleController.LocalService.class);
3959         }
3960         return mDeviceIdleController;
3961     }
3962
3963     /**
3964      * Update given flags when being used to request {@link PackageInfo}.
3965      */
3966     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3967         final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
3968         boolean triaged = true;
3969         if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3970                 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3971             // Caller is asking for component details, so they'd better be
3972             // asking for specific encryption matching behavior, or be triaged
3973             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3974                     | PackageManager.MATCH_DIRECT_BOOT_AWARE
3975                     | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3976                 triaged = false;
3977             }
3978         }
3979         if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3980                 | PackageManager.MATCH_SYSTEM_ONLY
3981                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3982             triaged = false;
3983         }
3984         if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
3985             enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
3986                     "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
3987                     + Debug.getCallers(5));
3988         } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
3989                 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
3990             // If the caller wants all packages and has a restricted profile associated with it,
3991             // then match all users. This is to make sure that launchers that need to access work
3992             // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
3993             // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
3994             flags |= PackageManager.MATCH_ANY_USER;
3995         }
3996         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3997             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3998                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3999         }
4000         return updateFlags(flags, userId);
4001     }
4002
4003     /**
4004      * Update given flags when being used to request {@link ApplicationInfo}.
4005      */
4006     private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4007         return updateFlagsForPackage(flags, userId, cookie);
4008     }
4009
4010     /**
4011      * Update given flags when being used to request {@link ComponentInfo}.
4012      */
4013     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4014         if (cookie instanceof Intent) {
4015             if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4016                 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4017             }
4018         }
4019
4020         boolean triaged = true;
4021         // Caller is asking for component details, so they'd better be
4022         // asking for specific encryption matching behavior, or be triaged
4023         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4024                 | PackageManager.MATCH_DIRECT_BOOT_AWARE
4025                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4026             triaged = false;
4027         }
4028         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4029             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4030                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4031         }
4032
4033         return updateFlags(flags, userId);
4034     }
4035
4036     /**
4037      * Update given intent when being used to request {@link ResolveInfo}.
4038      */
4039     private Intent updateIntentForResolve(Intent intent) {
4040         if (intent.getSelector() != null) {
4041             intent = intent.getSelector();
4042         }
4043         if (DEBUG_PREFERRED) {
4044             intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4045         }
4046         return intent;
4047     }
4048
4049     /**
4050      * Update given flags when being used to request {@link ResolveInfo}.
4051      * <p>Instant apps are resolved specially, depending upon context. Minimally,
4052      * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4053      * flag set. However, this flag is only honoured in three circumstances:
4054      * <ul>
4055      * <li>when called from a system process</li>
4056      * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4057      * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4058      * action and a {@code android.intent.category.BROWSABLE} category</li>
4059      * </ul>
4060      */
4061     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4062             boolean includeInstantApps) {
4063         // Safe mode means we shouldn't match any third-party components
4064         if (mSafeMode) {
4065             flags |= PackageManager.MATCH_SYSTEM_ONLY;
4066         }
4067         if (getInstantAppPackageName(callingUid) != null) {
4068             // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4069             flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4070             flags |= PackageManager.MATCH_INSTANT;
4071         } else {
4072             // Otherwise, prevent leaking ephemeral components
4073             final boolean isSpecialProcess =
4074                     callingUid == Process.SYSTEM_UID
4075                     || callingUid == Process.SHELL_UID
4076                     || callingUid == 0;
4077             final boolean allowMatchInstant =
4078                     (includeInstantApps
4079                             && Intent.ACTION_VIEW.equals(intent.getAction())
4080                             && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
4081                             && hasWebURI(intent))
4082                     || isSpecialProcess
4083                     || mContext.checkCallingOrSelfPermission(
4084                             android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
4085             flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4086             if (!allowMatchInstant) {
4087                 flags &= ~PackageManager.MATCH_INSTANT;
4088             }
4089         }
4090         return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4091     }
4092
4093     private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4094             int userId) {
4095         ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4096         if (ret != null) {
4097             rebaseEnabledOverlays(ret.applicationInfo, userId);
4098         }
4099         return ret;
4100     }
4101
4102     private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4103             PackageUserState state, int userId) {
4104         ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4105         if (ai != null) {
4106             rebaseEnabledOverlays(ai.applicationInfo, userId);
4107         }
4108         return ai;
4109     }
4110
4111     @Override
4112     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4113         if (!sUserManager.exists(userId)) return null;
4114         flags = updateFlagsForComponent(flags, userId, component);
4115         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4116                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
4117         synchronized (mPackages) {
4118             PackageParser.Activity a = mActivities.mActivities.get(component);
4119
4120             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4121             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4122                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4123                 if (ps == null) return null;
4124                 return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4125             }
4126             if (mResolveComponentName.equals(component)) {
4127                 return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4128                         userId);
4129             }
4130         }
4131         return null;
4132     }
4133
4134     @Override
4135     public boolean activitySupportsIntent(ComponentName component, Intent intent,
4136             String resolvedType) {
4137         synchronized (mPackages) {
4138             if (component.equals(mResolveComponentName)) {
4139                 // The resolver supports EVERYTHING!
4140                 return true;
4141             }
4142             PackageParser.Activity a = mActivities.mActivities.get(component);
4143             if (a == null) {
4144                 return false;
4145             }
4146             for (int i=0; i<a.intents.size(); i++) {
4147                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4148                         intent.getData(), intent.getCategories(), TAG) >= 0) {
4149                     return true;
4150                 }
4151             }
4152             return false;
4153         }
4154     }
4155
4156     @Override
4157     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4158         if (!sUserManager.exists(userId)) return null;
4159         flags = updateFlagsForComponent(flags, userId, component);
4160         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4161                 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4162         synchronized (mPackages) {
4163             PackageParser.Activity a = mReceivers.mActivities.get(component);
4164             if (DEBUG_PACKAGE_INFO) Log.v(
4165                 TAG, "getReceiverInfo " + component + ": " + a);
4166             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4167                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4168                 if (ps == null) return null;
4169                 return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4170             }
4171         }
4172         return null;
4173     }
4174
4175     @Override
4176     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) {
4177         if (!sUserManager.exists(userId)) return null;
4178         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4179
4180         flags = updateFlagsForPackage(flags, userId, null);
4181
4182         final boolean canSeeStaticLibraries =
4183                 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4184                         == PERMISSION_GRANTED
4185                 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4186                         == PERMISSION_GRANTED
4187                 || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES)
4188                         == PERMISSION_GRANTED
4189                 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4190                         == PERMISSION_GRANTED;
4191
4192         synchronized (mPackages) {
4193             List<SharedLibraryInfo> result = null;
4194
4195             final int libCount = mSharedLibraries.size();
4196             for (int i = 0; i < libCount; i++) {
4197                 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4198                 if (versionedLib == null) {
4199                     continue;
4200                 }
4201
4202                 final int versionCount = versionedLib.size();
4203                 for (int j = 0; j < versionCount; j++) {
4204                     SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4205                     if (!canSeeStaticLibraries && libInfo.isStatic()) {
4206                         break;
4207                     }
4208                     final long identity = Binder.clearCallingIdentity();
4209                     try {
4210                         // TODO: We will change version code to long, so in the new API it is long
4211                         PackageInfo packageInfo = getPackageInfoVersioned(
4212                                 libInfo.getDeclaringPackage(), flags, userId);
4213                         if (packageInfo == null) {
4214                             continue;
4215                         }
4216                     } finally {
4217                         Binder.restoreCallingIdentity(identity);
4218                     }
4219
4220                     SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4221                             libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(),
4222                             getPackagesUsingSharedLibraryLPr(libInfo, flags, userId));
4223
4224                     if (result == null) {
4225                         result = new ArrayList<>();
4226                     }
4227                     result.add(resLibInfo);
4228                 }
4229             }
4230
4231             return result != null ? new ParceledListSlice<>(result) : null;
4232         }
4233     }
4234
4235     private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4236             SharedLibraryInfo libInfo, int flags, int userId) {
4237         List<VersionedPackage> versionedPackages = null;
4238         final int packageCount = mSettings.mPackages.size();
4239         for (int i = 0; i < packageCount; i++) {
4240             PackageSetting ps = mSettings.mPackages.valueAt(i);
4241
4242             if (ps == null) {
4243                 continue;
4244             }
4245
4246             if (!ps.getUserState().get(userId).isAvailable(flags)) {
4247                 continue;
4248             }
4249
4250             final String libName = libInfo.getName();
4251             if (libInfo.isStatic()) {
4252                 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4253                 if (libIdx < 0) {
4254                     continue;
4255                 }
4256                 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4257                     continue;
4258                 }
4259                 if (versionedPackages == null) {
4260                     versionedPackages = new ArrayList<>();
4261                 }
4262                 // If the dependent is a static shared lib, use the public package name
4263                 String dependentPackageName = ps.name;
4264                 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4265                     dependentPackageName = ps.pkg.manifestPackageName;
4266                 }
4267                 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4268             } else if (ps.pkg != null) {
4269                 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4270                         || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4271                     if (versionedPackages == null) {
4272                         versionedPackages = new ArrayList<>();
4273                     }
4274                     versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4275                 }
4276             }
4277         }
4278
4279         return versionedPackages;
4280     }
4281
4282     @Override
4283     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4284         if (!sUserManager.exists(userId)) return null;
4285         flags = updateFlagsForComponent(flags, userId, component);
4286         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4287                 false /* requireFullPermission */, false /* checkShell */, "get service info");
4288         synchronized (mPackages) {
4289             PackageParser.Service s = mServices.mServices.get(component);
4290             if (DEBUG_PACKAGE_INFO) Log.v(
4291                 TAG, "getServiceInfo " + component + ": " + s);
4292             if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4293                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4294                 if (ps == null) return null;
4295                 ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4296                         ps.readUserState(userId), userId);
4297                 if (si != null) {
4298                     rebaseEnabledOverlays(si.applicationInfo, userId);
4299                 }
4300                 return si;
4301             }
4302         }
4303         return null;
4304     }
4305
4306     @Override
4307     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4308         if (!sUserManager.exists(userId)) return null;
4309         flags = updateFlagsForComponent(flags, userId, component);
4310         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4311                 false /* requireFullPermission */, false /* checkShell */, "get provider info");
4312         synchronized (mPackages) {
4313             PackageParser.Provider p = mProviders.mProviders.get(component);
4314             if (DEBUG_PACKAGE_INFO) Log.v(
4315                 TAG, "getProviderInfo " + component + ": " + p);
4316             if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4317                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4318                 if (ps == null) return null;
4319                 ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4320                         ps.readUserState(userId), userId);
4321                 if (pi != null) {
4322                     rebaseEnabledOverlays(pi.applicationInfo, userId);
4323                 }
4324                 return pi;
4325             }
4326         }
4327         return null;
4328     }
4329
4330     @Override
4331     public String[] getSystemSharedLibraryNames() {
4332         synchronized (mPackages) {
4333             Set<String> libs = null;
4334             final int libCount = mSharedLibraries.size();
4335             for (int i = 0; i < libCount; i++) {
4336                 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4337                 if (versionedLib == null) {
4338                     continue;
4339                 }
4340                 final int versionCount = versionedLib.size();
4341                 for (int j = 0; j < versionCount; j++) {
4342                     SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4343                     if (!libEntry.info.isStatic()) {
4344                         if (libs == null) {
4345                             libs = new ArraySet<>();
4346                         }
4347                         libs.add(libEntry.info.getName());
4348                         break;
4349                     }
4350                     PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4351                     if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4352                             UserHandle.getUserId(Binder.getCallingUid()))) {
4353                         if (libs == null) {
4354                             libs = new ArraySet<>();
4355                         }
4356                         libs.add(libEntry.info.getName());
4357                         break;
4358                     }
4359                 }
4360             }
4361
4362             if (libs != null) {
4363                 String[] libsArray = new String[libs.size()];
4364                 libs.toArray(libsArray);
4365                 return libsArray;
4366             }
4367
4368             return null;
4369         }
4370     }
4371
4372     @Override
4373     public @NonNull String getServicesSystemSharedLibraryPackageName() {
4374         synchronized (mPackages) {
4375             return mServicesSystemSharedLibraryPackageName;
4376         }
4377     }
4378
4379     @Override
4380     public @NonNull String getSharedSystemSharedLibraryPackageName() {
4381         synchronized (mPackages) {
4382             return mSharedSystemSharedLibraryPackageName;
4383         }
4384     }
4385
4386     private void updateSequenceNumberLP(String packageName, int[] userList) {
4387         for (int i = userList.length - 1; i >= 0; --i) {
4388             final int userId = userList[i];
4389             SparseArray<String> changedPackages = mChangedPackages.get(userId);
4390             if (changedPackages == null) {
4391                 changedPackages = new SparseArray<>();
4392                 mChangedPackages.put(userId, changedPackages);
4393             }
4394             Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4395             if (sequenceNumbers == null) {
4396                 sequenceNumbers = new HashMap<>();
4397                 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4398             }
4399             final Integer sequenceNumber = sequenceNumbers.get(packageName);
4400             if (sequenceNumber != null) {
4401                 changedPackages.remove(sequenceNumber);
4402             }
4403             changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4404             sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4405         }
4406         mChangedPackagesSequenceNumber++;
4407     }
4408
4409     @Override
4410     public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4411         synchronized (mPackages) {
4412             if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4413                 return null;
4414             }
4415             final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4416             if (changedPackages == null) {
4417                 return null;
4418             }
4419             final List<String> packageNames =
4420                     new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4421             for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4422                 final String packageName = changedPackages.get(i);
4423                 if (packageName != null) {
4424                     packageNames.add(packageName);
4425                 }
4426             }
4427             return packageNames.isEmpty()
4428                     ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4429         }
4430     }
4431
4432     @Override
4433     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4434         ArrayList<FeatureInfo> res;
4435         synchronized (mAvailableFeatures) {
4436             res = new ArrayList<>(mAvailableFeatures.size() + 1);
4437             res.addAll(mAvailableFeatures.values());
4438         }
4439         final FeatureInfo fi = new FeatureInfo();
4440         fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4441                 FeatureInfo.GL_ES_VERSION_UNDEFINED);
4442         res.add(fi);
4443
4444         return new ParceledListSlice<>(res);
4445     }
4446
4447     @Override
4448     public boolean hasSystemFeature(String name, int version) {
4449         synchronized (mAvailableFeatures) {
4450             final FeatureInfo feat = mAvailableFeatures.get(name);
4451             if (feat == null) {
4452                 return false;
4453             } else {
4454                 return feat.version >= version;
4455             }
4456         }
4457     }
4458
4459     @Override
4460     public int checkPermission(String permName, String pkgName, int userId) {
4461         if (!sUserManager.exists(userId)) {
4462             return PackageManager.PERMISSION_DENIED;
4463         }
4464
4465         synchronized (mPackages) {
4466             final PackageParser.Package p = mPackages.get(pkgName);
4467             if (p != null && p.mExtras != null) {
4468                 final PackageSetting ps = (PackageSetting) p.mExtras;
4469                 final PermissionsState permissionsState = ps.getPermissionsState();
4470                 if (permissionsState.hasPermission(permName, userId)) {
4471                     return PackageManager.PERMISSION_GRANTED;
4472                 }
4473                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4474                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4475                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4476                     return PackageManager.PERMISSION_GRANTED;
4477                 }
4478             }
4479         }
4480
4481         return PackageManager.PERMISSION_DENIED;
4482     }
4483
4484     @Override
4485     public int checkUidPermission(String permName, int uid) {
4486         final int userId = UserHandle.getUserId(uid);
4487
4488         if (!sUserManager.exists(userId)) {
4489             return PackageManager.PERMISSION_DENIED;
4490         }
4491
4492         synchronized (mPackages) {
4493             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4494             if (obj != null) {
4495                 final SettingBase ps = (SettingBase) obj;
4496                 final PermissionsState permissionsState = ps.getPermissionsState();
4497                 if (permissionsState.hasPermission(permName, userId)) {
4498                     return PackageManager.PERMISSION_GRANTED;
4499                 }
4500                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4501                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4502                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4503                     return PackageManager.PERMISSION_GRANTED;
4504                 }
4505             } else {
4506                 ArraySet<String> perms = mSystemPermissions.get(uid);
4507                 if (perms != null) {
4508                     if (perms.contains(permName)) {
4509                         return PackageManager.PERMISSION_GRANTED;
4510                     }
4511                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4512                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4513                         return PackageManager.PERMISSION_GRANTED;
4514                     }
4515                 }
4516             }
4517         }
4518
4519         return PackageManager.PERMISSION_DENIED;
4520     }
4521
4522     @Override
4523     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4524         if (UserHandle.getCallingUserId() != userId) {
4525             mContext.enforceCallingPermission(
4526                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4527                     "isPermissionRevokedByPolicy for user " + userId);
4528         }
4529
4530         if (checkPermission(permission, packageName, userId)
4531                 == PackageManager.PERMISSION_GRANTED) {
4532             return false;
4533         }
4534
4535         final long identity = Binder.clearCallingIdentity();
4536         try {
4537             final int flags = getPermissionFlags(permission, packageName, userId);
4538             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4539         } finally {
4540             Binder.restoreCallingIdentity(identity);
4541         }
4542     }
4543
4544     @Override
4545     public String getPermissionControllerPackageName() {
4546         synchronized (mPackages) {
4547             return mRequiredInstallerPackage;
4548         }
4549     }
4550
4551     /**
4552      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4553      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4554      * @param checkShell whether to prevent shell from access if there's a debugging restriction
4555      * @param message the message to log on security exception
4556      */
4557     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4558             boolean checkShell, String message) {
4559         if (userId < 0) {
4560             throw new IllegalArgumentException("Invalid userId " + userId);
4561         }
4562         if (checkShell) {
4563             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4564         }
4565         if (userId == UserHandle.getUserId(callingUid)) return;
4566         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4567             if (requireFullPermission) {
4568                 mContext.enforceCallingOrSelfPermission(
4569                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4570             } else {
4571                 try {
4572                     mContext.enforceCallingOrSelfPermission(
4573                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4574                 } catch (SecurityException se) {
4575                     mContext.enforceCallingOrSelfPermission(
4576                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4577                 }
4578             }
4579         }
4580     }
4581
4582     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4583         if (callingUid == Process.SHELL_UID) {
4584             if (userHandle >= 0
4585                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
4586                 throw new SecurityException("Shell does not have permission to access user "
4587                         + userHandle);
4588             } else if (userHandle < 0) {
4589                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4590                         + Debug.getCallers(3));
4591             }
4592         }
4593     }
4594
4595     private BasePermission findPermissionTreeLP(String permName) {
4596         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4597             if (permName.startsWith(bp.name) &&
4598                     permName.length() > bp.name.length() &&
4599                     permName.charAt(bp.name.length()) == '.') {
4600                 return bp;
4601             }
4602         }
4603         return null;
4604     }
4605
4606     private BasePermission checkPermissionTreeLP(String permName) {
4607         if (permName != null) {
4608             BasePermission bp = findPermissionTreeLP(permName);
4609             if (bp != null) {
4610                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4611                     return bp;
4612                 }
4613                 throw new SecurityException("Calling uid "
4614                         + Binder.getCallingUid()
4615                         + " is not allowed to add to permission tree "
4616                         + bp.name + " owned by uid " + bp.uid);
4617             }
4618         }
4619         throw new SecurityException("No permission tree found for " + permName);
4620     }
4621
4622     static boolean compareStrings(CharSequence s1, CharSequence s2) {
4623         if (s1 == null) {
4624             return s2 == null;
4625         }
4626         if (s2 == null) {
4627             return false;
4628         }
4629         if (s1.getClass() != s2.getClass()) {
4630             return false;
4631         }
4632         return s1.equals(s2);
4633     }
4634
4635     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4636         if (pi1.icon != pi2.icon) return false;
4637         if (pi1.logo != pi2.logo) return false;
4638         if (pi1.protectionLevel != pi2.protectionLevel) return false;
4639         if (!compareStrings(pi1.name, pi2.name)) return false;
4640         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4641         // We'll take care of setting this one.
4642         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4643         // These are not currently stored in settings.
4644         //if (!compareStrings(pi1.group, pi2.group)) return false;
4645         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4646         //if (pi1.labelRes != pi2.labelRes) return false;
4647         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4648         return true;
4649     }
4650
4651     int permissionInfoFootprint(PermissionInfo info) {
4652         int size = info.name.length();
4653         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4654         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4655         return size;
4656     }
4657
4658     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4659         int size = 0;
4660         for (BasePermission perm : mSettings.mPermissions.values()) {
4661             if (perm.uid == tree.uid) {
4662                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4663             }
4664         }
4665         return size;
4666     }
4667
4668     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4669         // We calculate the max size of permissions defined by this uid and throw
4670         // if that plus the size of 'info' would exceed our stated maximum.
4671         if (tree.uid != Process.SYSTEM_UID) {
4672             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4673             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4674                 throw new SecurityException("Permission tree size cap exceeded");
4675             }
4676         }
4677     }
4678
4679     boolean addPermissionLocked(PermissionInfo info, boolean async) {
4680         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4681             throw new SecurityException("Label must be specified in permission");
4682         }
4683         BasePermission tree = checkPermissionTreeLP(info.name);
4684         BasePermission bp = mSettings.mPermissions.get(info.name);
4685         boolean added = bp == null;
4686         boolean changed = true;
4687         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4688         if (added) {
4689             enforcePermissionCapLocked(info, tree);
4690             bp = new BasePermission(info.name, tree.sourcePackage,
4691                     BasePermission.TYPE_DYNAMIC);
4692         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4693             throw new SecurityException(
4694                     "Not allowed to modify non-dynamic permission "
4695                     + info.name);
4696         } else {
4697             if (bp.protectionLevel == fixedLevel
4698                     && bp.perm.owner.equals(tree.perm.owner)
4699                     && bp.uid == tree.uid
4700                     && comparePermissionInfos(bp.perm.info, info)) {
4701                 changed = false;
4702             }
4703         }
4704         bp.protectionLevel = fixedLevel;
4705         info = new PermissionInfo(info);
4706         info.protectionLevel = fixedLevel;
4707         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4708         bp.perm.info.packageName = tree.perm.info.packageName;
4709         bp.uid = tree.uid;
4710         if (added) {
4711             mSettings.mPermissions.put(info.name, bp);
4712         }
4713         if (changed) {
4714             if (!async) {
4715                 mSettings.writeLPr();
4716             } else {
4717                 scheduleWriteSettingsLocked();
4718             }
4719         }
4720         return added;
4721     }
4722
4723     @Override
4724     public boolean addPermission(PermissionInfo info) {
4725         synchronized (mPackages) {
4726             return addPermissionLocked(info, false);
4727         }
4728     }
4729
4730     @Override
4731     public boolean addPermissionAsync(PermissionInfo info) {
4732         synchronized (mPackages) {
4733             return addPermissionLocked(info, true);
4734         }
4735     }
4736
4737     @Override
4738     public void removePermission(String name) {
4739         synchronized (mPackages) {
4740             checkPermissionTreeLP(name);
4741             BasePermission bp = mSettings.mPermissions.get(name);
4742             if (bp != null) {
4743                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
4744                     throw new SecurityException(
4745                             "Not allowed to modify non-dynamic permission "
4746                             + name);
4747                 }
4748                 mSettings.mPermissions.remove(name);
4749                 mSettings.writeLPr();
4750             }
4751         }
4752     }
4753
4754     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4755             BasePermission bp) {
4756         int index = pkg.requestedPermissions.indexOf(bp.name);
4757         if (index == -1) {
4758             throw new SecurityException("Package " + pkg.packageName
4759                     + " has not requested permission " + bp.name);
4760         }
4761         if (!bp.isRuntime() && !bp.isDevelopment()) {
4762             throw new SecurityException("Permission " + bp.name
4763                     + " is not a changeable permission type");
4764         }
4765     }
4766
4767     @Override
4768     public void grantRuntimePermission(String packageName, String name, final int userId) {
4769         grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4770     }
4771
4772     private void grantRuntimePermission(String packageName, String name, final int userId,
4773             boolean overridePolicy) {
4774         if (!sUserManager.exists(userId)) {
4775             Log.e(TAG, "No such user:" + userId);
4776             return;
4777         }
4778
4779         mContext.enforceCallingOrSelfPermission(
4780                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4781                 "grantRuntimePermission");
4782
4783         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4784                 true /* requireFullPermission */, true /* checkShell */,
4785                 "grantRuntimePermission");
4786
4787         final int uid;
4788         final SettingBase sb;
4789
4790         synchronized (mPackages) {
4791             final PackageParser.Package pkg = mPackages.get(packageName);
4792             if (pkg == null) {
4793                 throw new IllegalArgumentException("Unknown package: " + packageName);
4794             }
4795
4796             final BasePermission bp = mSettings.mPermissions.get(name);
4797             if (bp == null) {
4798                 throw new IllegalArgumentException("Unknown permission: " + name);
4799             }
4800
4801             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4802
4803             // If a permission review is required for legacy apps we represent
4804             // their permissions as always granted runtime ones since we need
4805             // to keep the review required permission flag per user while an
4806             // install permission's state is shared across all users.
4807             if (mPermissionReviewRequired
4808                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4809                     && bp.isRuntime()) {
4810                 return;
4811             }
4812
4813             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4814             sb = (SettingBase) pkg.mExtras;
4815             if (sb == null) {
4816                 throw new IllegalArgumentException("Unknown package: " + packageName);
4817             }
4818
4819             final PermissionsState permissionsState = sb.getPermissionsState();
4820
4821             final int flags = permissionsState.getPermissionFlags(name, userId);
4822             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4823                 throw new SecurityException("Cannot grant system fixed permission "
4824                         + name + " for package " + packageName);
4825             }
4826             if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4827                 throw new SecurityException("Cannot grant policy fixed permission "
4828                         + name + " for package " + packageName);
4829             }
4830
4831             if (bp.isDevelopment()) {
4832                 // Development permissions must be handled specially, since they are not
4833                 // normal runtime permissions.  For now they apply to all users.
4834                 if (permissionsState.grantInstallPermission(bp) !=
4835                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4836                     scheduleWriteSettingsLocked();
4837                 }
4838                 return;
4839             }
4840
4841             final PackageSetting ps = mSettings.mPackages.get(packageName);
4842             if (ps.getInstantApp(userId) && !bp.isInstant()) {
4843                 throw new SecurityException("Cannot grant non-ephemeral permission"
4844                         + name + " for package " + packageName);
4845             }
4846
4847             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4848                 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4849                 return;
4850             }
4851
4852             final int result = permissionsState.grantRuntimePermission(bp, userId);
4853             switch (result) {
4854                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4855                     return;
4856                 }
4857
4858                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4859                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4860                     mHandler.post(new Runnable() {
4861                         @Override
4862                         public void run() {
4863                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4864                         }
4865                     });
4866                 }
4867                 break;
4868             }
4869
4870             if (bp.isRuntime()) {
4871                 logPermissionGranted(mContext, name, packageName);
4872             }
4873
4874             mOnPermissionChangeListeners.onPermissionsChanged(uid);
4875
4876             // Not critical if that is lost - app has to request again.
4877             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4878         }
4879
4880         // Only need to do this if user is initialized. Otherwise it's a new user
4881         // and there are no processes running as the user yet and there's no need
4882         // to make an expensive call to remount processes for the changed permissions.
4883         if (READ_EXTERNAL_STORAGE.equals(name)
4884                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
4885             final long token = Binder.clearCallingIdentity();
4886             try {
4887                 if (sUserManager.isInitialized(userId)) {
4888                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
4889                             StorageManagerInternal.class);
4890                     storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
4891                 }
4892             } finally {
4893                 Binder.restoreCallingIdentity(token);
4894             }
4895         }
4896     }
4897
4898     @Override
4899     public void revokeRuntimePermission(String packageName, String name, int userId) {
4900         revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4901     }
4902
4903     private void revokeRuntimePermission(String packageName, String name, int userId,
4904             boolean overridePolicy) {
4905         if (!sUserManager.exists(userId)) {
4906             Log.e(TAG, "No such user:" + userId);
4907             return;
4908         }
4909
4910         mContext.enforceCallingOrSelfPermission(
4911                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4912                 "revokeRuntimePermission");
4913
4914         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4915                 true /* requireFullPermission */, true /* checkShell */,
4916                 "revokeRuntimePermission");
4917
4918         final int appId;
4919
4920         synchronized (mPackages) {
4921             final PackageParser.Package pkg = mPackages.get(packageName);
4922             if (pkg == null) {
4923                 throw new IllegalArgumentException("Unknown package: " + packageName);
4924             }
4925
4926             final BasePermission bp = mSettings.mPermissions.get(name);
4927             if (bp == null) {
4928                 throw new IllegalArgumentException("Unknown permission: " + name);
4929             }
4930
4931             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4932
4933             // If a permission review is required for legacy apps we represent
4934             // their permissions as always granted runtime ones since we need
4935             // to keep the review required permission flag per user while an
4936             // install permission's state is shared across all users.
4937             if (mPermissionReviewRequired
4938                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4939                     && bp.isRuntime()) {
4940                 return;
4941             }
4942
4943             SettingBase sb = (SettingBase) pkg.mExtras;
4944             if (sb == null) {
4945                 throw new IllegalArgumentException("Unknown package: " + packageName);
4946             }
4947
4948             final PermissionsState permissionsState = sb.getPermissionsState();
4949
4950             final int flags = permissionsState.getPermissionFlags(name, userId);
4951             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4952                 throw new SecurityException("Cannot revoke system fixed permission "
4953                         + name + " for package " + packageName);
4954             }
4955             if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4956                 throw new SecurityException("Cannot revoke policy fixed permission "
4957                         + name + " for package " + packageName);
4958             }
4959
4960             if (bp.isDevelopment()) {
4961                 // Development permissions must be handled specially, since they are not
4962                 // normal runtime permissions.  For now they apply to all users.
4963                 if (permissionsState.revokeInstallPermission(bp) !=
4964                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4965                     scheduleWriteSettingsLocked();
4966                 }
4967                 return;
4968             }
4969
4970             if (permissionsState.revokeRuntimePermission(bp, userId) ==
4971                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
4972                 return;
4973             }
4974
4975             if (bp.isRuntime()) {
4976                 logPermissionRevoked(mContext, name, packageName);
4977             }
4978
4979             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4980
4981             // Critical, after this call app should never have the permission.
4982             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4983
4984             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4985         }
4986
4987         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4988     }
4989
4990     /**
4991      * Get the first event id for the permission.
4992      *
4993      * <p>There are four events for each permission: <ul>
4994      *     <li>Request permission: first id + 0</li>
4995      *     <li>Grant permission: first id + 1</li>
4996      *     <li>Request for permission denied: first id + 2</li>
4997      *     <li>Revoke permission: first id + 3</li>
4998      * </ul></p>
4999      *
5000      * @param name name of the permission
5001      *
5002      * @return The first event id for the permission
5003      */
5004     private static int getBaseEventId(@NonNull String name) {
5005         int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5006
5007         if (eventIdIndex == -1) {
5008             if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5009                     || "user".equals(Build.TYPE)) {
5010                 Log.i(TAG, "Unknown permission " + name);
5011
5012                 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5013             } else {
5014                 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5015                 //
5016                 // Also update
5017                 // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5018                 // - metrics_constants.proto
5019                 throw new IllegalStateException("Unknown permission " + name);
5020             }
5021         }
5022
5023         return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5024     }
5025
5026     /**
5027      * Log that a permission was revoked.
5028      *
5029      * @param context Context of the caller
5030      * @param name name of the permission
5031      * @param packageName package permission if for
5032      */
5033     private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5034             @NonNull String packageName) {
5035         MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5036     }
5037
5038     /**
5039      * Log that a permission request was granted.
5040      *
5041      * @param context Context of the caller
5042      * @param name name of the permission
5043      * @param packageName package permission if for
5044      */
5045     private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5046             @NonNull String packageName) {
5047         MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5048     }
5049
5050     @Override
5051     public void resetRuntimePermissions() {
5052         mContext.enforceCallingOrSelfPermission(
5053                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5054                 "revokeRuntimePermission");
5055
5056         int callingUid = Binder.getCallingUid();
5057         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5058             mContext.enforceCallingOrSelfPermission(
5059                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5060                     "resetRuntimePermissions");
5061         }
5062
5063         synchronized (mPackages) {
5064             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5065             for (int userId : UserManagerService.getInstance().getUserIds()) {
5066                 final int packageCount = mPackages.size();
5067                 for (int i = 0; i < packageCount; i++) {
5068                     PackageParser.Package pkg = mPackages.valueAt(i);
5069                     if (!(pkg.mExtras instanceof PackageSetting)) {
5070                         continue;
5071                     }
5072                     PackageSetting ps = (PackageSetting) pkg.mExtras;
5073                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5074                 }
5075             }
5076         }
5077     }
5078
5079     @Override
5080     public int getPermissionFlags(String name, String packageName, int userId) {
5081         if (!sUserManager.exists(userId)) {
5082             return 0;
5083         }
5084
5085         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5086
5087         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5088                 true /* requireFullPermission */, false /* checkShell */,
5089                 "getPermissionFlags");
5090
5091         synchronized (mPackages) {
5092             final PackageParser.Package pkg = mPackages.get(packageName);
5093             if (pkg == null) {
5094                 return 0;
5095             }
5096
5097             final BasePermission bp = mSettings.mPermissions.get(name);
5098             if (bp == null) {
5099                 return 0;
5100             }
5101
5102             SettingBase sb = (SettingBase) pkg.mExtras;
5103             if (sb == null) {
5104                 return 0;
5105             }
5106
5107             PermissionsState permissionsState = sb.getPermissionsState();
5108             return permissionsState.getPermissionFlags(name, userId);
5109         }
5110     }
5111
5112     @Override
5113     public void updatePermissionFlags(String name, String packageName, int flagMask,
5114             int flagValues, int userId) {
5115         if (!sUserManager.exists(userId)) {
5116             return;
5117         }
5118
5119         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5120
5121         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5122                 true /* requireFullPermission */, true /* checkShell */,
5123                 "updatePermissionFlags");
5124
5125         // Only the system can change these flags and nothing else.
5126         if (getCallingUid() != Process.SYSTEM_UID) {
5127             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5128             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5129             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5130             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5131             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5132         }
5133
5134         synchronized (mPackages) {
5135             final PackageParser.Package pkg = mPackages.get(packageName);
5136             if (pkg == null) {
5137                 throw new IllegalArgumentException("Unknown package: " + packageName);
5138             }
5139
5140             final BasePermission bp = mSettings.mPermissions.get(name);
5141             if (bp == null) {
5142                 throw new IllegalArgumentException("Unknown permission: " + name);
5143             }
5144
5145             SettingBase sb = (SettingBase) pkg.mExtras;
5146             if (sb == null) {
5147                 throw new IllegalArgumentException("Unknown package: " + packageName);
5148             }
5149
5150             PermissionsState permissionsState = sb.getPermissionsState();
5151
5152             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5153
5154             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5155                 // Install and runtime permissions are stored in different places,
5156                 // so figure out what permission changed and persist the change.
5157                 if (permissionsState.getInstallPermissionState(name) != null) {
5158                     scheduleWriteSettingsLocked();
5159                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5160                         || hadState) {
5161                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5162                 }
5163             }
5164         }
5165     }
5166
5167     /**
5168      * Update the permission flags for all packages and runtime permissions of a user in order
5169      * to allow device or profile owner to remove POLICY_FIXED.
5170      */
5171     @Override
5172     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5173         if (!sUserManager.exists(userId)) {
5174             return;
5175         }
5176
5177         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5178
5179         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5180                 true /* requireFullPermission */, true /* checkShell */,
5181                 "updatePermissionFlagsForAllApps");
5182
5183         // Only the system can change system fixed flags.
5184         if (getCallingUid() != Process.SYSTEM_UID) {
5185             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5186             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5187         }
5188
5189         synchronized (mPackages) {
5190             boolean changed = false;
5191             final int packageCount = mPackages.size();
5192             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5193                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5194                 SettingBase sb = (SettingBase) pkg.mExtras;
5195                 if (sb == null) {
5196                     continue;
5197                 }
5198                 PermissionsState permissionsState = sb.getPermissionsState();
5199                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5200                         userId, flagMask, flagValues);
5201             }
5202             if (changed) {
5203                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5204             }
5205         }
5206     }
5207
5208     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5209         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5210                 != PackageManager.PERMISSION_GRANTED
5211             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5212                 != PackageManager.PERMISSION_GRANTED) {
5213             throw new SecurityException(message + " requires "
5214                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5215                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5216         }
5217     }
5218
5219     @Override
5220     public boolean shouldShowRequestPermissionRationale(String permissionName,
5221             String packageName, int userId) {
5222         if (UserHandle.getCallingUserId() != userId) {
5223             mContext.enforceCallingPermission(
5224                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5225                     "canShowRequestPermissionRationale for user " + userId);
5226         }
5227
5228         final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5229         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5230             return false;
5231         }
5232
5233         if (checkPermission(permissionName, packageName, userId)
5234                 == PackageManager.PERMISSION_GRANTED) {
5235             return false;
5236         }
5237
5238         final int flags;
5239
5240         final long identity = Binder.clearCallingIdentity();
5241         try {
5242             flags = getPermissionFlags(permissionName,
5243                     packageName, userId);
5244         } finally {
5245             Binder.restoreCallingIdentity(identity);
5246         }
5247
5248         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5249                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5250                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
5251
5252         if ((flags & fixedFlags) != 0) {
5253             return false;
5254         }
5255
5256         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5257     }
5258
5259     @Override
5260     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5261         mContext.enforceCallingOrSelfPermission(
5262                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5263                 "addOnPermissionsChangeListener");
5264
5265         synchronized (mPackages) {
5266             mOnPermissionChangeListeners.addListenerLocked(listener);
5267         }
5268     }
5269
5270     @Override
5271     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5272         synchronized (mPackages) {
5273             mOnPermissionChangeListeners.removeListenerLocked(listener);
5274         }
5275     }
5276
5277     @Override
5278     public boolean isProtectedBroadcast(String actionName) {
5279         synchronized (mPackages) {
5280             if (mProtectedBroadcasts.contains(actionName)) {
5281                 return true;
5282             } else if (actionName != null) {
5283                 // TODO: remove these terrible hacks
5284                 if (actionName.startsWith("android.net.netmon.lingerExpired")
5285                         || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5286                         || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5287                         || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5288                     return true;
5289                 }
5290             }
5291         }
5292         return false;
5293     }
5294
5295     @Override
5296     public int checkSignatures(String pkg1, String pkg2) {
5297         synchronized (mPackages) {
5298             final PackageParser.Package p1 = mPackages.get(pkg1);
5299             final PackageParser.Package p2 = mPackages.get(pkg2);
5300             if (p1 == null || p1.mExtras == null
5301                     || p2 == null || p2.mExtras == null) {
5302                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5303             }
5304             return compareSignatures(p1.mSignatures, p2.mSignatures);
5305         }
5306     }
5307
5308     @Override
5309     public int checkUidSignatures(int uid1, int uid2) {
5310         // Map to base uids.
5311         uid1 = UserHandle.getAppId(uid1);
5312         uid2 = UserHandle.getAppId(uid2);
5313         // reader
5314         synchronized (mPackages) {
5315             Signature[] s1;
5316             Signature[] s2;
5317             Object obj = mSettings.getUserIdLPr(uid1);
5318             if (obj != null) {
5319                 if (obj instanceof SharedUserSetting) {
5320                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5321                 } else if (obj instanceof PackageSetting) {
5322                     s1 = ((PackageSetting)obj).signatures.mSignatures;
5323                 } else {
5324                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5325                 }
5326             } else {
5327                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5328             }
5329             obj = mSettings.getUserIdLPr(uid2);
5330             if (obj != null) {
5331                 if (obj instanceof SharedUserSetting) {
5332                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5333                 } else if (obj instanceof PackageSetting) {
5334                     s2 = ((PackageSetting)obj).signatures.mSignatures;
5335                 } else {
5336                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5337                 }
5338             } else {
5339                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5340             }
5341             return compareSignatures(s1, s2);
5342         }
5343     }
5344
5345     /**
5346      * This method should typically only be used when granting or revoking
5347      * permissions, since the app may immediately restart after this call.
5348      * <p>
5349      * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5350      * guard your work against the app being relaunched.
5351      */
5352     private void killUid(int appId, int userId, String reason) {
5353         final long identity = Binder.clearCallingIdentity();
5354         try {
5355             IActivityManager am = ActivityManager.getService();
5356             if (am != null) {
5357                 try {
5358                     am.killUid(appId, userId, reason);
5359                 } catch (RemoteException e) {
5360                     /* ignore - same process */
5361                 }
5362             }
5363         } finally {
5364             Binder.restoreCallingIdentity(identity);
5365         }
5366     }
5367
5368     /**
5369      * Compares two sets of signatures. Returns:
5370      * <br />
5371      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5372      * <br />
5373      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5374      * <br />
5375      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5376      * <br />
5377      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5378      * <br />
5379      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5380      */
5381     static int compareSignatures(Signature[] s1, Signature[] s2) {
5382         if (s1 == null) {
5383             return s2 == null
5384                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
5385                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5386         }
5387
5388         if (s2 == null) {
5389             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5390         }
5391
5392         if (s1.length != s2.length) {
5393             return PackageManager.SIGNATURE_NO_MATCH;
5394         }
5395
5396         // Since both signature sets are of size 1, we can compare without HashSets.
5397         if (s1.length == 1) {
5398             return s1[0].equals(s2[0]) ?
5399                     PackageManager.SIGNATURE_MATCH :
5400                     PackageManager.SIGNATURE_NO_MATCH;
5401         }
5402
5403         ArraySet<Signature> set1 = new ArraySet<Signature>();
5404         for (Signature sig : s1) {
5405             set1.add(sig);
5406         }
5407         ArraySet<Signature> set2 = new ArraySet<Signature>();
5408         for (Signature sig : s2) {
5409             set2.add(sig);
5410         }
5411         // Make sure s2 contains all signatures in s1.
5412         if (set1.equals(set2)) {
5413             return PackageManager.SIGNATURE_MATCH;
5414         }
5415         return PackageManager.SIGNATURE_NO_MATCH;
5416     }
5417
5418     /**
5419      * If the database version for this type of package (internal storage or
5420      * external storage) is less than the version where package signatures
5421      * were updated, return true.
5422      */
5423     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5424         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5425         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5426     }
5427
5428     /**
5429      * Used for backward compatibility to make sure any packages with
5430      * certificate chains get upgraded to the new style. {@code existingSigs}
5431      * will be in the old format (since they were stored on disk from before the
5432      * system upgrade) and {@code scannedSigs} will be in the newer format.
5433      */
5434     private int compareSignaturesCompat(PackageSignatures existingSigs,
5435             PackageParser.Package scannedPkg) {
5436         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5437             return PackageManager.SIGNATURE_NO_MATCH;
5438         }
5439
5440         ArraySet<Signature> existingSet = new ArraySet<Signature>();
5441         for (Signature sig : existingSigs.mSignatures) {
5442             existingSet.add(sig);
5443         }
5444         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5445         for (Signature sig : scannedPkg.mSignatures) {
5446             try {
5447                 Signature[] chainSignatures = sig.getChainSignatures();
5448                 for (Signature chainSig : chainSignatures) {
5449                     scannedCompatSet.add(chainSig);
5450                 }
5451             } catch (CertificateEncodingException e) {
5452                 scannedCompatSet.add(sig);
5453             }
5454         }
5455         /*
5456          * Make sure the expanded scanned set contains all signatures in the
5457          * existing one.
5458          */
5459         if (scannedCompatSet.equals(existingSet)) {
5460             // Migrate the old signatures to the new scheme.
5461             existingSigs.assignSignatures(scannedPkg.mSignatures);
5462             // The new KeySets will be re-added later in the scanning process.
5463             synchronized (mPackages) {
5464                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5465             }
5466             return PackageManager.SIGNATURE_MATCH;
5467         }
5468         return PackageManager.SIGNATURE_NO_MATCH;
5469     }
5470
5471     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5472         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5473         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5474     }
5475
5476     private int compareSignaturesRecover(PackageSignatures existingSigs,
5477             PackageParser.Package scannedPkg) {
5478         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5479             return PackageManager.SIGNATURE_NO_MATCH;
5480         }
5481
5482         String msg = null;
5483         try {
5484             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5485                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5486                         + scannedPkg.packageName);
5487                 return PackageManager.SIGNATURE_MATCH;
5488             }
5489         } catch (CertificateException e) {
5490             msg = e.getMessage();
5491         }
5492
5493         logCriticalInfo(Log.INFO,
5494                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5495         return PackageManager.SIGNATURE_NO_MATCH;
5496     }
5497
5498     @Override
5499     public List<String> getAllPackages() {
5500         synchronized (mPackages) {
5501             return new ArrayList<String>(mPackages.keySet());
5502         }
5503     }
5504
5505     @Override
5506     public String[] getPackagesForUid(int uid) {
5507         final int userId = UserHandle.getUserId(uid);
5508         uid = UserHandle.getAppId(uid);
5509         // reader
5510         synchronized (mPackages) {
5511             Object obj = mSettings.getUserIdLPr(uid);
5512             if (obj instanceof SharedUserSetting) {
5513                 final SharedUserSetting sus = (SharedUserSetting) obj;
5514                 final int N = sus.packages.size();
5515                 String[] res = new String[N];
5516                 final Iterator<PackageSetting> it = sus.packages.iterator();
5517                 int i = 0;
5518                 while (it.hasNext()) {
5519                     PackageSetting ps = it.next();
5520                     if (ps.getInstalled(userId)) {
5521                         res[i++] = ps.name;
5522                     } else {
5523                         res = ArrayUtils.removeElement(String.class, res, res[i]);
5524                     }
5525                 }
5526                 return res;
5527             } else if (obj instanceof PackageSetting) {
5528                 final PackageSetting ps = (PackageSetting) obj;
5529                 if (ps.getInstalled(userId)) {
5530                     return new String[]{ps.name};
5531                 }
5532             }
5533         }
5534         return null;
5535     }
5536
5537     @Override
5538     public String getNameForUid(int uid) {
5539         // reader
5540         synchronized (mPackages) {
5541             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5542             if (obj instanceof SharedUserSetting) {
5543                 final SharedUserSetting sus = (SharedUserSetting) obj;
5544                 return sus.name + ":" + sus.userId;
5545             } else if (obj instanceof PackageSetting) {
5546                 final PackageSetting ps = (PackageSetting) obj;
5547                 return ps.name;
5548             }
5549         }
5550         return null;
5551     }
5552
5553     @Override
5554     public int getUidForSharedUser(String sharedUserName) {
5555         if(sharedUserName == null) {
5556             return -1;
5557         }
5558         // reader
5559         synchronized (mPackages) {
5560             SharedUserSetting suid;
5561             try {
5562                 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5563                 if (suid != null) {
5564                     return suid.userId;
5565                 }
5566             } catch (PackageManagerException ignore) {
5567                 // can't happen, but, still need to catch it
5568             }
5569             return -1;
5570         }
5571     }
5572
5573     @Override
5574     public int getFlagsForUid(int uid) {
5575         synchronized (mPackages) {
5576             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5577             if (obj instanceof SharedUserSetting) {
5578                 final SharedUserSetting sus = (SharedUserSetting) obj;
5579                 return sus.pkgFlags;
5580             } else if (obj instanceof PackageSetting) {
5581                 final PackageSetting ps = (PackageSetting) obj;
5582                 return ps.pkgFlags;
5583             }
5584         }
5585         return 0;
5586     }
5587
5588     @Override
5589     public int getPrivateFlagsForUid(int uid) {
5590         synchronized (mPackages) {
5591             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5592             if (obj instanceof SharedUserSetting) {
5593                 final SharedUserSetting sus = (SharedUserSetting) obj;
5594                 return sus.pkgPrivateFlags;
5595             } else if (obj instanceof PackageSetting) {
5596                 final PackageSetting ps = (PackageSetting) obj;
5597                 return ps.pkgPrivateFlags;
5598             }
5599         }
5600         return 0;
5601     }
5602
5603     @Override
5604     public boolean isUidPrivileged(int uid) {
5605         uid = UserHandle.getAppId(uid);
5606         // reader
5607         synchronized (mPackages) {
5608             Object obj = mSettings.getUserIdLPr(uid);
5609             if (obj instanceof SharedUserSetting) {
5610                 final SharedUserSetting sus = (SharedUserSetting) obj;
5611                 final Iterator<PackageSetting> it = sus.packages.iterator();
5612                 while (it.hasNext()) {
5613                     if (it.next().isPrivileged()) {
5614                         return true;
5615                     }
5616                 }
5617             } else if (obj instanceof PackageSetting) {
5618                 final PackageSetting ps = (PackageSetting) obj;
5619                 return ps.isPrivileged();
5620             }
5621         }
5622         return false;
5623     }
5624
5625     @Override
5626     public String[] getAppOpPermissionPackages(String permissionName) {
5627         synchronized (mPackages) {
5628             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5629             if (pkgs == null) {
5630                 return null;
5631             }
5632             return pkgs.toArray(new String[pkgs.size()]);
5633         }
5634     }
5635
5636     @Override
5637     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5638             int flags, int userId) {
5639         return resolveIntentInternal(
5640                 intent, resolvedType, flags, userId, false /*includeInstantApps*/);
5641     }
5642
5643     private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5644             int flags, int userId, boolean includeInstantApps) {
5645         try {
5646             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5647
5648             if (!sUserManager.exists(userId)) return null;
5649             final int callingUid = Binder.getCallingUid();
5650             flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
5651             enforceCrossUserPermission(callingUid, userId,
5652                     false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5653
5654             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5655             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5656                     flags, userId, includeInstantApps);
5657             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5658
5659             final ResolveInfo bestChoice =
5660                     chooseBestActivity(intent, resolvedType, flags, query, userId);
5661             return bestChoice;
5662         } finally {
5663             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5664         }
5665     }
5666
5667     @Override
5668     public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5669         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5670             throw new SecurityException(
5671                     "findPersistentPreferredActivity can only be run by the system");
5672         }
5673         if (!sUserManager.exists(userId)) {
5674             return null;
5675         }
5676         final int callingUid = Binder.getCallingUid();
5677         intent = updateIntentForResolve(intent);
5678         final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5679         final int flags = updateFlagsForResolve(
5680                 0, userId, intent, callingUid, false /*includeInstantApps*/);
5681         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5682                 userId);
5683         synchronized (mPackages) {
5684             return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5685                     userId);
5686         }
5687     }
5688
5689     @Override
5690     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5691             IntentFilter filter, int match, ComponentName activity) {
5692         final int userId = UserHandle.getCallingUserId();
5693         if (DEBUG_PREFERRED) {
5694             Log.v(TAG, "setLastChosenActivity intent=" + intent
5695                 + " resolvedType=" + resolvedType
5696                 + " flags=" + flags
5697                 + " filter=" + filter
5698                 + " match=" + match
5699                 + " activity=" + activity);
5700             filter.dump(new PrintStreamPrinter(System.out), "    ");
5701         }
5702         intent.setComponent(null);
5703         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5704                 userId);
5705         // Find any earlier preferred or last chosen entries and nuke them
5706         findPreferredActivity(intent, resolvedType,
5707                 flags, query, 0, false, true, false, userId);
5708         // Add the new activity as the last chosen for this filter
5709         addPreferredActivityInternal(filter, match, null, activity, false, userId,
5710                 "Setting last chosen");
5711     }
5712
5713     @Override
5714     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5715         final int userId = UserHandle.getCallingUserId();
5716         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5717         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5718                 userId);
5719         return findPreferredActivity(intent, resolvedType, flags, query, 0,
5720                 false, false, false, userId);
5721     }
5722
5723     /**
5724      * Returns whether or not instant apps have been disabled remotely.
5725      */
5726     private boolean isEphemeralDisabled() {
5727         return mEphemeralAppsDisabled;
5728     }
5729
5730     private boolean isEphemeralAllowed(
5731             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5732             boolean skipPackageCheck) {
5733         final int callingUser = UserHandle.getCallingUserId();
5734         if (mInstantAppResolverConnection == null) {
5735             return false;
5736         }
5737         if (mInstantAppInstallerActivity == null) {
5738             return false;
5739         }
5740         if (intent.getComponent() != null) {
5741             return false;
5742         }
5743         if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5744             return false;
5745         }
5746         if (!skipPackageCheck && intent.getPackage() != null) {
5747             return false;
5748         }
5749         final boolean isWebUri = hasWebURI(intent);
5750         if (!isWebUri || intent.getData().getHost() == null) {
5751             return false;
5752         }
5753         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5754         // Or if there's already an ephemeral app installed that handles the action
5755         synchronized (mPackages) {
5756             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5757             for (int n = 0; n < count; n++) {
5758                 final ResolveInfo info = resolvedActivities.get(n);
5759                 final String packageName = info.activityInfo.packageName;
5760                 final PackageSetting ps = mSettings.mPackages.get(packageName);
5761                 if (ps != null) {
5762                     // only check domain verification status if the app is not a browser
5763                     if (!info.handleAllWebDataURI) {
5764                         // Try to get the status from User settings first
5765                         final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5766                         final int status = (int) (packedStatus >> 32);
5767                         if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5768                             || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5769                             if (DEBUG_EPHEMERAL) {
5770                                 Slog.v(TAG, "DENY instant app;"
5771                                     + " pkg: " + packageName + ", status: " + status);
5772                             }
5773                             return false;
5774                         }
5775                     }
5776                     if (ps.getInstantApp(userId)) {
5777                         if (DEBUG_EPHEMERAL) {
5778                             Slog.v(TAG, "DENY instant app installed;"
5779                                     + " pkg: " + packageName);
5780                         }
5781                         return false;
5782                     }
5783                 }
5784             }
5785         }
5786         // We've exhausted all ways to deny ephemeral application; let the system look for them.
5787         return true;
5788     }
5789
5790     private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5791             Intent origIntent, String resolvedType, String callingPackage,
5792             int userId) {
5793         final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5794                 new InstantAppRequest(responseObj, origIntent, resolvedType,
5795                         callingPackage, userId));
5796         mHandler.sendMessage(msg);
5797     }
5798
5799     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5800             int flags, List<ResolveInfo> query, int userId) {
5801         if (query != null) {
5802             final int N = query.size();
5803             if (N == 1) {
5804                 return query.get(0);
5805             } else if (N > 1) {
5806                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5807                 // If there is more than one activity with the same priority,
5808                 // then let the user decide between them.
5809                 ResolveInfo r0 = query.get(0);
5810                 ResolveInfo r1 = query.get(1);
5811                 if (DEBUG_INTENT_MATCHING || debug) {
5812                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5813                             + r1.activityInfo.name + "=" + r1.priority);
5814                 }
5815                 // If the first activity has a higher priority, or a different
5816                 // default, then it is always desirable to pick it.
5817                 if (r0.priority != r1.priority
5818                         || r0.preferredOrder != r1.preferredOrder
5819                         || r0.isDefault != r1.isDefault) {
5820                     return query.get(0);
5821                 }
5822                 // If we have saved a preference for a preferred activity for
5823                 // this Intent, use that.
5824                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5825                         flags, query, r0.priority, true, false, debug, userId);
5826                 if (ri != null) {
5827                     return ri;
5828                 }
5829                 // If we have an ephemeral app, use it
5830                 for (int i = 0; i < N; i++) {
5831                     ri = query.get(i);
5832                     if (ri.activityInfo.applicationInfo.isInstantApp()) {
5833                         return ri;
5834                     }
5835                 }
5836                 ri = new ResolveInfo(mResolveInfo);
5837                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
5838                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5839                 // If all of the options come from the same package, show the application's
5840                 // label and icon instead of the generic resolver's.
5841                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5842                 // and then throw away the ResolveInfo itself, meaning that the caller loses
5843                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5844                 // a fallback for this case; we only set the target package's resources on
5845                 // the ResolveInfo, not the ActivityInfo.
5846                 final String intentPackage = intent.getPackage();
5847                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5848                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5849                     ri.resolvePackageName = intentPackage;
5850                     if (userNeedsBadging(userId)) {
5851                         ri.noResourceId = true;
5852                     } else {
5853                         ri.icon = appi.icon;
5854                     }
5855                     ri.iconResourceId = appi.icon;
5856                     ri.labelRes = appi.labelRes;
5857                 }
5858                 ri.activityInfo.applicationInfo = new ApplicationInfo(
5859                         ri.activityInfo.applicationInfo);
5860                 if (userId != 0) {
5861                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5862                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5863                 }
5864                 // Make sure that the resolver is displayable in car mode
5865                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5866                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5867                 return ri;
5868             }
5869         }
5870         return null;
5871     }
5872
5873     /**
5874      * Return true if the given list is not empty and all of its contents have
5875      * an activityInfo with the given package name.
5876      */
5877     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5878         if (ArrayUtils.isEmpty(list)) {
5879             return false;
5880         }
5881         for (int i = 0, N = list.size(); i < N; i++) {
5882             final ResolveInfo ri = list.get(i);
5883             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5884             if (ai == null || !packageName.equals(ai.packageName)) {
5885                 return false;
5886             }
5887         }
5888         return true;
5889     }
5890
5891     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5892             int flags, List<ResolveInfo> query, boolean debug, int userId) {
5893         final int N = query.size();
5894         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5895                 .get(userId);
5896         // Get the list of persistent preferred activities that handle the intent
5897         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5898         List<PersistentPreferredActivity> pprefs = ppir != null
5899                 ? ppir.queryIntent(intent, resolvedType,
5900                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5901                         userId)
5902                 : null;
5903         if (pprefs != null && pprefs.size() > 0) {
5904             final int M = pprefs.size();
5905             for (int i=0; i<M; i++) {
5906                 final PersistentPreferredActivity ppa = pprefs.get(i);
5907                 if (DEBUG_PREFERRED || debug) {
5908                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5909                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5910                             + "\n  component=" + ppa.mComponent);
5911                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5912                 }
5913                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5914                         flags | MATCH_DISABLED_COMPONENTS, userId);
5915                 if (DEBUG_PREFERRED || debug) {
5916                     Slog.v(TAG, "Found persistent preferred activity:");
5917                     if (ai != null) {
5918                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5919                     } else {
5920                         Slog.v(TAG, "  null");
5921                     }
5922                 }
5923                 if (ai == null) {
5924                     // This previously registered persistent preferred activity
5925                     // component is no longer known. Ignore it and do NOT remove it.
5926                     continue;
5927                 }
5928                 for (int j=0; j<N; j++) {
5929                     final ResolveInfo ri = query.get(j);
5930                     if (!ri.activityInfo.applicationInfo.packageName
5931                             .equals(ai.applicationInfo.packageName)) {
5932                         continue;
5933                     }
5934                     if (!ri.activityInfo.name.equals(ai.name)) {
5935                         continue;
5936                     }
5937                     //  Found a persistent preference that can handle the intent.
5938                     if (DEBUG_PREFERRED || debug) {
5939                         Slog.v(TAG, "Returning persistent preferred activity: " +
5940                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5941                     }
5942                     return ri;
5943                 }
5944             }
5945         }
5946         return null;
5947     }
5948
5949     // TODO: handle preferred activities missing while user has amnesia
5950     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5951             List<ResolveInfo> query, int priority, boolean always,
5952             boolean removeMatches, boolean debug, int userId) {
5953         if (!sUserManager.exists(userId)) return null;
5954         final int callingUid = Binder.getCallingUid();
5955         flags = updateFlagsForResolve(
5956                 flags, userId, intent, callingUid, false /*includeInstantApps*/);
5957         intent = updateIntentForResolve(intent);
5958         // writer
5959         synchronized (mPackages) {
5960             // Try to find a matching persistent preferred activity.
5961             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5962                     debug, userId);
5963
5964             // If a persistent preferred activity matched, use it.
5965             if (pri != null) {
5966                 return pri;
5967             }
5968
5969             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5970             // Get the list of preferred activities that handle the intent
5971             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5972             List<PreferredActivity> prefs = pir != null
5973                     ? pir.queryIntent(intent, resolvedType,
5974                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5975                             userId)
5976                     : null;
5977             if (prefs != null && prefs.size() > 0) {
5978                 boolean changed = false;
5979                 try {
5980                     // First figure out how good the original match set is.
5981                     // We will only allow preferred activities that came
5982                     // from the same match quality.
5983                     int match = 0;
5984
5985                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5986
5987                     final int N = query.size();
5988                     for (int j=0; j<N; j++) {
5989                         final ResolveInfo ri = query.get(j);
5990                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5991                                 + ": 0x" + Integer.toHexString(match));
5992                         if (ri.match > match) {
5993                             match = ri.match;
5994                         }
5995                     }
5996
5997                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5998                             + Integer.toHexString(match));
5999
6000                     match &= IntentFilter.MATCH_CATEGORY_MASK;
6001                     final int M = prefs.size();
6002                     for (int i=0; i<M; i++) {
6003                         final PreferredActivity pa = prefs.get(i);
6004                         if (DEBUG_PREFERRED || debug) {
6005                             Slog.v(TAG, "Checking PreferredActivity ds="
6006                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6007                                     + "\n  component=" + pa.mPref.mComponent);
6008                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6009                         }
6010                         if (pa.mPref.mMatch != match) {
6011                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6012                                     + Integer.toHexString(pa.mPref.mMatch));
6013                             continue;
6014                         }
6015                         // If it's not an "always" type preferred activity and that's what we're
6016                         // looking for, skip it.
6017                         if (always && !pa.mPref.mAlways) {
6018                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6019                             continue;
6020                         }
6021                         final ActivityInfo ai = getActivityInfo(
6022                                 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6023                                         | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6024                                 userId);
6025                         if (DEBUG_PREFERRED || debug) {
6026                             Slog.v(TAG, "Found preferred activity:");
6027                             if (ai != null) {
6028                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6029                             } else {
6030                                 Slog.v(TAG, "  null");
6031                             }
6032                         }
6033                         if (ai == null) {
6034                             // This previously registered preferred activity
6035                             // component is no longer known.  Most likely an update
6036                             // to the app was installed and in the new version this
6037                             // component no longer exists.  Clean it up by removing
6038                             // it from the preferred activities list, and skip it.
6039                             Slog.w(TAG, "Removing dangling preferred activity: "
6040                                     + pa.mPref.mComponent);
6041                             pir.removeFilter(pa);
6042                             changed = true;
6043                             continue;
6044                         }
6045                         for (int j=0; j<N; j++) {
6046                             final ResolveInfo ri = query.get(j);
6047                             if (!ri.activityInfo.applicationInfo.packageName
6048                                     .equals(ai.applicationInfo.packageName)) {
6049                                 continue;
6050                             }
6051                             if (!ri.activityInfo.name.equals(ai.name)) {
6052                                 continue;
6053                             }
6054
6055                             if (removeMatches) {
6056                                 pir.removeFilter(pa);
6057                                 changed = true;
6058                                 if (DEBUG_PREFERRED) {
6059                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6060                                 }
6061                                 break;
6062                             }
6063
6064                             // Okay we found a previously set preferred or last chosen app.
6065                             // If the result set is different from when this
6066                             // was created, we need to clear it and re-ask the
6067                             // user their preference, if we're looking for an "always" type entry.
6068                             if (always && !pa.mPref.sameSet(query)) {
6069                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
6070                                         + intent + " type " + resolvedType);
6071                                 if (DEBUG_PREFERRED) {
6072                                     Slog.v(TAG, "Removing preferred activity since set changed "
6073                                             + pa.mPref.mComponent);
6074                                 }
6075                                 pir.removeFilter(pa);
6076                                 // Re-add the filter as a "last chosen" entry (!always)
6077                                 PreferredActivity lastChosen = new PreferredActivity(
6078                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6079                                 pir.addFilter(lastChosen);
6080                                 changed = true;
6081                                 return null;
6082                             }
6083
6084                             // Yay! Either the set matched or we're looking for the last chosen
6085                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6086                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6087                             return ri;
6088                         }
6089                     }
6090                 } finally {
6091                     if (changed) {
6092                         if (DEBUG_PREFERRED) {
6093                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6094                         }
6095                         scheduleWritePackageRestrictionsLocked(userId);
6096                     }
6097                 }
6098             }
6099         }
6100         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6101         return null;
6102     }
6103
6104     /*
6105      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6106      */
6107     @Override
6108     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6109             int targetUserId) {
6110         mContext.enforceCallingOrSelfPermission(
6111                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6112         List<CrossProfileIntentFilter> matches =
6113                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6114         if (matches != null) {
6115             int size = matches.size();
6116             for (int i = 0; i < size; i++) {
6117                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
6118             }
6119         }
6120         if (hasWebURI(intent)) {
6121             // cross-profile app linking works only towards the parent.
6122             final int callingUid = Binder.getCallingUid();
6123             final UserInfo parent = getProfileParent(sourceUserId);
6124             synchronized(mPackages) {
6125                 int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6126                         false /*includeInstantApps*/);
6127                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6128                         intent, resolvedType, flags, sourceUserId, parent.id);
6129                 return xpDomainInfo != null;
6130             }
6131         }
6132         return false;
6133     }
6134
6135     private UserInfo getProfileParent(int userId) {
6136         final long identity = Binder.clearCallingIdentity();
6137         try {
6138             return sUserManager.getProfileParent(userId);
6139         } finally {
6140             Binder.restoreCallingIdentity(identity);
6141         }
6142     }
6143
6144     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6145             String resolvedType, int userId) {
6146         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6147         if (resolver != null) {
6148             return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6149         }
6150         return null;
6151     }
6152
6153     @Override
6154     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6155             String resolvedType, int flags, int userId) {
6156         try {
6157             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6158
6159             return new ParceledListSlice<>(
6160                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6161         } finally {
6162             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6163         }
6164     }
6165
6166     /**
6167      * Returns the package name of the calling Uid if it's an instant app. If it isn't
6168      * instant, returns {@code null}.
6169      */
6170     private String getInstantAppPackageName(int callingUid) {
6171         // If the caller is an isolated app use the owner's uid for the lookup.
6172         if (Process.isIsolated(callingUid)) {
6173             callingUid = mIsolatedOwners.get(callingUid);
6174         }
6175         final int appId = UserHandle.getAppId(callingUid);
6176         synchronized (mPackages) {
6177             final Object obj = mSettings.getUserIdLPr(appId);
6178             if (obj instanceof PackageSetting) {
6179                 final PackageSetting ps = (PackageSetting) obj;
6180                 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6181                 return isInstantApp ? ps.pkg.packageName : null;
6182             }
6183         }
6184         return null;
6185     }
6186
6187     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6188             String resolvedType, int flags, int userId) {
6189         return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6190     }
6191
6192     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6193             String resolvedType, int flags, int userId, boolean includeInstantApps) {
6194         if (!sUserManager.exists(userId)) return Collections.emptyList();
6195         final int callingUid = Binder.getCallingUid();
6196         final String instantAppPkgName = getInstantAppPackageName(callingUid);
6197         flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
6198         enforceCrossUserPermission(callingUid, userId,
6199                 false /* requireFullPermission */, false /* checkShell */,
6200                 "query intent activities");
6201         ComponentName comp = intent.getComponent();
6202         if (comp == null) {
6203             if (intent.getSelector() != null) {
6204                 intent = intent.getSelector();
6205                 comp = intent.getComponent();
6206             }
6207         }
6208
6209         if (comp != null) {
6210             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6211             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6212             if (ai != null) {
6213                 // When specifying an explicit component, we prevent the activity from being
6214                 // used when either 1) the calling package is normal and the activity is within
6215                 // an ephemeral application or 2) the calling package is ephemeral and the
6216                 // activity is not visible to ephemeral applications.
6217                 final boolean matchInstantApp =
6218                         (flags & PackageManager.MATCH_INSTANT) != 0;
6219                 final boolean matchVisibleToInstantAppOnly =
6220                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6221                 final boolean isCallerInstantApp =
6222                         instantAppPkgName != null;
6223                 final boolean isTargetSameInstantApp =
6224                         comp.getPackageName().equals(instantAppPkgName);
6225                 final boolean isTargetInstantApp =
6226                         (ai.applicationInfo.privateFlags
6227                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6228                 final boolean isTargetHiddenFromInstantApp =
6229                         (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
6230                 final boolean blockResolution =
6231                         !isTargetSameInstantApp
6232                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6233                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
6234                                         && isTargetHiddenFromInstantApp));
6235                 if (!blockResolution) {
6236                     final ResolveInfo ri = new ResolveInfo();
6237                     ri.activityInfo = ai;
6238                     list.add(ri);
6239                 }
6240             }
6241             return applyPostResolutionFilter(list, instantAppPkgName);
6242         }
6243
6244         // reader
6245         boolean sortResult = false;
6246         boolean addEphemeral = false;
6247         List<ResolveInfo> result;
6248         final String pkgName = intent.getPackage();
6249         final boolean ephemeralDisabled = isEphemeralDisabled();
6250         synchronized (mPackages) {
6251             if (pkgName == null) {
6252                 List<CrossProfileIntentFilter> matchingFilters =
6253                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6254                 // Check for results that need to skip the current profile.
6255                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6256                         resolvedType, flags, userId);
6257                 if (xpResolveInfo != null) {
6258                     List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6259                     xpResult.add(xpResolveInfo);
6260                     return applyPostResolutionFilter(
6261                             filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6262                 }
6263
6264                 // Check for results in the current profile.
6265                 result = filterIfNotSystemUser(mActivities.queryIntent(
6266                         intent, resolvedType, flags, userId), userId);
6267                 addEphemeral = !ephemeralDisabled
6268                         && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
6269                 // Check for cross profile results.
6270                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6271                 xpResolveInfo = queryCrossProfileIntents(
6272                         matchingFilters, intent, resolvedType, flags, userId,
6273                         hasNonNegativePriorityResult);
6274                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6275                     boolean isVisibleToUser = filterIfNotSystemUser(
6276                             Collections.singletonList(xpResolveInfo), userId).size() > 0;
6277                     if (isVisibleToUser) {
6278                         result.add(xpResolveInfo);
6279                         sortResult = true;
6280                     }
6281                 }
6282                 if (hasWebURI(intent)) {
6283                     CrossProfileDomainInfo xpDomainInfo = null;
6284                     final UserInfo parent = getProfileParent(userId);
6285                     if (parent != null) {
6286                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6287                                 flags, userId, parent.id);
6288                     }
6289                     if (xpDomainInfo != null) {
6290                         if (xpResolveInfo != null) {
6291                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
6292                             // in the result.
6293                             result.remove(xpResolveInfo);
6294                         }
6295                         if (result.size() == 0 && !addEphemeral) {
6296                             // No result in current profile, but found candidate in parent user.
6297                             // And we are not going to add emphemeral app, so we can return the
6298                             // result straight away.
6299                             result.add(xpDomainInfo.resolveInfo);
6300                             return applyPostResolutionFilter(result, instantAppPkgName);
6301                         }
6302                     } else if (result.size() <= 1 && !addEphemeral) {
6303                         // No result in parent user and <= 1 result in current profile, and we
6304                         // are not going to add emphemeral app, so we can return the result without
6305                         // further processing.
6306                         return applyPostResolutionFilter(result, instantAppPkgName);
6307                     }
6308                     // We have more than one candidate (combining results from current and parent
6309                     // profile), so we need filtering and sorting.
6310                     result = filterCandidatesWithDomainPreferredActivitiesLPr(
6311                             intent, flags, result, xpDomainInfo, userId);
6312                     sortResult = true;
6313                 }
6314             } else {
6315                 final PackageParser.Package pkg = mPackages.get(pkgName);
6316                 if (pkg != null) {
6317                     return applyPostResolutionFilter(filterIfNotSystemUser(
6318                             mActivities.queryIntentForPackage(
6319                                     intent, resolvedType, flags, pkg.activities, userId),
6320                             userId), instantAppPkgName);
6321                 } else {
6322                     // the caller wants to resolve for a particular package; however, there
6323                     // were no installed results, so, try to find an ephemeral result
6324                     addEphemeral = !ephemeralDisabled
6325                             && isEphemeralAllowed(
6326                                     intent, null /*result*/, userId, true /*skipPackageCheck*/);
6327                     result = new ArrayList<ResolveInfo>();
6328                 }
6329             }
6330         }
6331         if (addEphemeral) {
6332             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6333             final InstantAppRequest requestObject = new InstantAppRequest(
6334                     null /*responseObj*/, intent /*origIntent*/, resolvedType,
6335                     null /*callingPackage*/, userId);
6336             final AuxiliaryResolveInfo auxiliaryResponse =
6337                     InstantAppResolver.doInstantAppResolutionPhaseOne(
6338                             mContext, mInstantAppResolverConnection, requestObject);
6339             if (auxiliaryResponse != null) {
6340                 if (DEBUG_EPHEMERAL) {
6341                     Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6342                 }
6343                 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6344                 final PackageSetting ps =
6345                         mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6346                 if (ps != null) {
6347                     ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6348                             mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6349                     ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6350                     ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6351                     // make sure this resolver is the default
6352                     ephemeralInstaller.isDefault = true;
6353                     ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6354                             | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6355                     // add a non-generic filter
6356                     ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6357                     ephemeralInstaller.filter.addDataPath(
6358                             intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6359                     ephemeralInstaller.instantAppAvailable = true;
6360                     result.add(ephemeralInstaller);
6361                 }
6362             }
6363             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6364         }
6365         if (sortResult) {
6366             Collections.sort(result, mResolvePrioritySorter);
6367         }
6368         return applyPostResolutionFilter(result, instantAppPkgName);
6369     }
6370
6371     private static class CrossProfileDomainInfo {
6372         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6373         ResolveInfo resolveInfo;
6374         /* Best domain verification status of the activities found in the other profile */
6375         int bestDomainVerificationStatus;
6376     }
6377
6378     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6379             String resolvedType, int flags, int sourceUserId, int parentUserId) {
6380         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6381                 sourceUserId)) {
6382             return null;
6383         }
6384         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6385                 resolvedType, flags, parentUserId);
6386
6387         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6388             return null;
6389         }
6390         CrossProfileDomainInfo result = null;
6391         int size = resultTargetUser.size();
6392         for (int i = 0; i < size; i++) {
6393             ResolveInfo riTargetUser = resultTargetUser.get(i);
6394             // Intent filter verification is only for filters that specify a host. So don't return
6395             // those that handle all web uris.
6396             if (riTargetUser.handleAllWebDataURI) {
6397                 continue;
6398             }
6399             String packageName = riTargetUser.activityInfo.packageName;
6400             PackageSetting ps = mSettings.mPackages.get(packageName);
6401             if (ps == null) {
6402                 continue;
6403             }
6404             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6405             int status = (int)(verificationState >> 32);
6406             if (result == null) {
6407                 result = new CrossProfileDomainInfo();
6408                 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6409                         sourceUserId, parentUserId);
6410                 result.bestDomainVerificationStatus = status;
6411             } else {
6412                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6413                         result.bestDomainVerificationStatus);
6414             }
6415         }
6416         // Don't consider matches with status NEVER across profiles.
6417         if (result != null && result.bestDomainVerificationStatus
6418                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6419             return null;
6420         }
6421         return result;
6422     }
6423
6424     /**
6425      * Verification statuses are ordered from the worse to the best, except for
6426      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6427      */
6428     private int bestDomainVerificationStatus(int status1, int status2) {
6429         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6430             return status2;
6431         }
6432         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6433             return status1;
6434         }
6435         return (int) MathUtils.max(status1, status2);
6436     }
6437
6438     private boolean isUserEnabled(int userId) {
6439         long callingId = Binder.clearCallingIdentity();
6440         try {
6441             UserInfo userInfo = sUserManager.getUserInfo(userId);
6442             return userInfo != null && userInfo.isEnabled();
6443         } finally {
6444             Binder.restoreCallingIdentity(callingId);
6445         }
6446     }
6447
6448     /**
6449      * Filter out activities with systemUserOnly flag set, when current user is not System.
6450      *
6451      * @return filtered list
6452      */
6453     private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6454         if (userId == UserHandle.USER_SYSTEM) {
6455             return resolveInfos;
6456         }
6457         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6458             ResolveInfo info = resolveInfos.get(i);
6459             if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6460                 resolveInfos.remove(i);
6461             }
6462         }
6463         return resolveInfos;
6464     }
6465
6466     /**
6467      * Filters out ephemeral activities.
6468      * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6469      * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6470      *
6471      * @param resolveInfos The pre-filtered list of resolved activities
6472      * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6473      *          is performed.
6474      * @return A filtered list of resolved activities.
6475      */
6476     private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6477             String ephemeralPkgName) {
6478         // TODO: When adding on-demand split support for non-instant apps, remove this check
6479         // and always apply post filtering
6480         if (ephemeralPkgName == null) {
6481             return resolveInfos;
6482         }
6483         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6484             final ResolveInfo info = resolveInfos.get(i);
6485             final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6486             // allow activities that are defined in the provided package
6487             if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6488                 if (info.activityInfo.splitName != null
6489                         && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6490                                 info.activityInfo.splitName)) {
6491                     // requested activity is defined in a split that hasn't been installed yet.
6492                     // add the installer to the resolve list
6493                     if (DEBUG_EPHEMERAL) {
6494                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6495                     }
6496                     final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6497                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6498                             info.activityInfo.packageName, info.activityInfo.splitName,
6499                             info.activityInfo.applicationInfo.versionCode);
6500                     // make sure this resolver is the default
6501                     installerInfo.isDefault = true;
6502                     installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6503                             | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6504                     // add a non-generic filter
6505                     installerInfo.filter = new IntentFilter();
6506                     // load resources from the correct package
6507                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6508                     resolveInfos.set(i, installerInfo);
6509                 }
6510                 continue;
6511             }
6512             // allow activities that have been explicitly exposed to ephemeral apps
6513             if (!isEphemeralApp
6514                     && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
6515                 continue;
6516             }
6517             resolveInfos.remove(i);
6518         }
6519         return resolveInfos;
6520     }
6521
6522     /**
6523      * @param resolveInfos list of resolve infos in descending priority order
6524      * @return if the list contains a resolve info with non-negative priority
6525      */
6526     private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6527         return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6528     }
6529
6530     private static boolean hasWebURI(Intent intent) {
6531         if (intent.getData() == null) {
6532             return false;
6533         }
6534         final String scheme = intent.getScheme();
6535         if (TextUtils.isEmpty(scheme)) {
6536             return false;
6537         }
6538         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6539     }
6540
6541     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6542             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6543             int userId) {
6544         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6545
6546         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6547             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6548                     candidates.size());
6549         }
6550
6551         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6552         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6553         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6554         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6555         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6556         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6557
6558         synchronized (mPackages) {
6559             final int count = candidates.size();
6560             // First, try to use linked apps. Partition the candidates into four lists:
6561             // one for the final results, one for the "do not use ever", one for "undefined status"
6562             // and finally one for "browser app type".
6563             for (int n=0; n<count; n++) {
6564                 ResolveInfo info = candidates.get(n);
6565                 String packageName = info.activityInfo.packageName;
6566                 PackageSetting ps = mSettings.mPackages.get(packageName);
6567                 if (ps != null) {
6568                     // Add to the special match all list (Browser use case)
6569                     if (info.handleAllWebDataURI) {
6570                         matchAllList.add(info);
6571                         continue;
6572                     }
6573                     // Try to get the status from User settings first
6574                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6575                     int status = (int)(packedStatus >> 32);
6576                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6577                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6578                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
6579                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6580                                     + " : linkgen=" + linkGeneration);
6581                         }
6582                         // Use link-enabled generation as preferredOrder, i.e.
6583                         // prefer newly-enabled over earlier-enabled.
6584                         info.preferredOrder = linkGeneration;
6585                         alwaysList.add(info);
6586                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6587                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
6588                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6589                         }
6590                         neverList.add(info);
6591                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6592                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
6593                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6594                         }
6595                         alwaysAskList.add(info);
6596                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6597                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6598                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
6599                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6600                         }
6601                         undefinedList.add(info);
6602                     }
6603                 }
6604             }
6605
6606             // We'll want to include browser possibilities in a few cases
6607             boolean includeBrowser = false;
6608
6609             // First try to add the "always" resolution(s) for the current user, if any
6610             if (alwaysList.size() > 0) {
6611                 result.addAll(alwaysList);
6612             } else {
6613                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
6614                 result.addAll(undefinedList);
6615                 // Maybe add one for the other profile.
6616                 if (xpDomainInfo != null && (
6617                         xpDomainInfo.bestDomainVerificationStatus
6618                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6619                     result.add(xpDomainInfo.resolveInfo);
6620                 }
6621                 includeBrowser = true;
6622             }
6623
6624             // The presence of any 'always ask' alternatives means we'll also offer browsers.
6625             // If there were 'always' entries their preferred order has been set, so we also
6626             // back that off to make the alternatives equivalent
6627             if (alwaysAskList.size() > 0) {
6628                 for (ResolveInfo i : result) {
6629                     i.preferredOrder = 0;
6630                 }
6631                 result.addAll(alwaysAskList);
6632                 includeBrowser = true;
6633             }
6634
6635             if (includeBrowser) {
6636                 // Also add browsers (all of them or only the default one)
6637                 if (DEBUG_DOMAIN_VERIFICATION) {
6638                     Slog.v(TAG, "   ...including browsers in candidate set");
6639                 }
6640                 if ((matchFlags & MATCH_ALL) != 0) {
6641                     result.addAll(matchAllList);
6642                 } else {
6643                     // Browser/generic handling case.  If there's a default browser, go straight
6644                     // to that (but only if there is no other higher-priority match).
6645                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6646                     int maxMatchPrio = 0;
6647                     ResolveInfo defaultBrowserMatch = null;
6648                     final int numCandidates = matchAllList.size();
6649                     for (int n = 0; n < numCandidates; n++) {
6650                         ResolveInfo info = matchAllList.get(n);
6651                         // track the highest overall match priority...
6652                         if (info.priority > maxMatchPrio) {
6653                             maxMatchPrio = info.priority;
6654                         }
6655                         // ...and the highest-priority default browser match
6656                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6657                             if (defaultBrowserMatch == null
6658                                     || (defaultBrowserMatch.priority < info.priority)) {
6659                                 if (debug) {
6660                                     Slog.v(TAG, "Considering default browser match " + info);
6661                                 }
6662                                 defaultBrowserMatch = info;
6663                             }
6664                         }
6665                     }
6666                     if (defaultBrowserMatch != null
6667                             && defaultBrowserMatch.priority >= maxMatchPrio
6668                             && !TextUtils.isEmpty(defaultBrowserPackageName))
6669                     {
6670                         if (debug) {
6671                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6672                         }
6673                         result.add(defaultBrowserMatch);
6674                     } else {
6675                         result.addAll(matchAllList);
6676                     }
6677                 }
6678
6679                 // If there is nothing selected, add all candidates and remove the ones that the user
6680                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6681                 if (result.size() == 0) {
6682                     result.addAll(candidates);
6683                     result.removeAll(neverList);
6684                 }
6685             }
6686         }
6687         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6688             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6689                     result.size());
6690             for (ResolveInfo info : result) {
6691                 Slog.v(TAG, "  + " + info.activityInfo);
6692             }
6693         }
6694         return result;
6695     }
6696
6697     // Returns a packed value as a long:
6698     //
6699     // high 'int'-sized word: link status: undefined/ask/never/always.
6700     // low 'int'-sized word: relative priority among 'always' results.
6701     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6702         long result = ps.getDomainVerificationStatusForUser(userId);
6703         // if none available, get the master status
6704         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6705             if (ps.getIntentFilterVerificationInfo() != null) {
6706                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6707             }
6708         }
6709         return result;
6710     }
6711
6712     private ResolveInfo querySkipCurrentProfileIntents(
6713             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6714             int flags, int sourceUserId) {
6715         if (matchingFilters != null) {
6716             int size = matchingFilters.size();
6717             for (int i = 0; i < size; i ++) {
6718                 CrossProfileIntentFilter filter = matchingFilters.get(i);
6719                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6720                     // Checking if there are activities in the target user that can handle the
6721                     // intent.
6722                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6723                             resolvedType, flags, sourceUserId);
6724                     if (resolveInfo != null) {
6725                         return resolveInfo;
6726                     }
6727                 }
6728             }
6729         }
6730         return null;
6731     }
6732
6733     // Return matching ResolveInfo in target user if any.
6734     private ResolveInfo queryCrossProfileIntents(
6735             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6736             int flags, int sourceUserId, boolean matchInCurrentProfile) {
6737         if (matchingFilters != null) {
6738             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6739             // match the same intent. For performance reasons, it is better not to
6740             // run queryIntent twice for the same userId
6741             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6742             int size = matchingFilters.size();
6743             for (int i = 0; i < size; i++) {
6744                 CrossProfileIntentFilter filter = matchingFilters.get(i);
6745                 int targetUserId = filter.getTargetUserId();
6746                 boolean skipCurrentProfile =
6747                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6748                 boolean skipCurrentProfileIfNoMatchFound =
6749                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6750                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6751                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6752                     // Checking if there are activities in the target user that can handle the
6753                     // intent.
6754                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6755                             resolvedType, flags, sourceUserId);
6756                     if (resolveInfo != null) return resolveInfo;
6757                     alreadyTriedUserIds.put(targetUserId, true);
6758                 }
6759             }
6760         }
6761         return null;
6762     }
6763
6764     /**
6765      * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6766      * will forward the intent to the filter's target user.
6767      * Otherwise, returns null.
6768      */
6769     private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6770             String resolvedType, int flags, int sourceUserId) {
6771         int targetUserId = filter.getTargetUserId();
6772         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6773                 resolvedType, flags, targetUserId);
6774         if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6775             // If all the matches in the target profile are suspended, return null.
6776             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6777                 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6778                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6779                     return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6780                             targetUserId);
6781                 }
6782             }
6783         }
6784         return null;
6785     }
6786
6787     private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6788             int sourceUserId, int targetUserId) {
6789         ResolveInfo forwardingResolveInfo = new ResolveInfo();
6790         long ident = Binder.clearCallingIdentity();
6791         boolean targetIsProfile;
6792         try {
6793             targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
6794         } finally {
6795             Binder.restoreCallingIdentity(ident);
6796         }
6797         String className;
6798         if (targetIsProfile) {
6799             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
6800         } else {
6801             className = FORWARD_INTENT_TO_PARENT;
6802         }
6803         ComponentName forwardingActivityComponentName = new ComponentName(
6804                 mAndroidApplication.packageName, className);
6805         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
6806                 sourceUserId);
6807         if (!targetIsProfile) {
6808             forwardingActivityInfo.showUserIcon = targetUserId;
6809             forwardingResolveInfo.noResourceId = true;
6810         }
6811         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
6812         forwardingResolveInfo.priority = 0;
6813         forwardingResolveInfo.preferredOrder = 0;
6814         forwardingResolveInfo.match = 0;
6815         forwardingResolveInfo.isDefault = true;
6816         forwardingResolveInfo.filter = filter;
6817         forwardingResolveInfo.targetUserId = targetUserId;
6818         return forwardingResolveInfo;
6819     }
6820
6821     @Override
6822     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
6823             Intent[] specifics, String[] specificTypes, Intent intent,
6824             String resolvedType, int flags, int userId) {
6825         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
6826                 specificTypes, intent, resolvedType, flags, userId));
6827     }
6828
6829     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
6830             Intent[] specifics, String[] specificTypes, Intent intent,
6831             String resolvedType, int flags, int userId) {
6832         if (!sUserManager.exists(userId)) return Collections.emptyList();
6833         final int callingUid = Binder.getCallingUid();
6834         flags = updateFlagsForResolve(flags, userId, intent, callingUid,
6835                 false /*includeInstantApps*/);
6836         enforceCrossUserPermission(callingUid, userId,
6837                 false /*requireFullPermission*/, false /*checkShell*/,
6838                 "query intent activity options");
6839         final String resultsAction = intent.getAction();
6840
6841         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
6842                 | PackageManager.GET_RESOLVED_FILTER, userId);
6843
6844         if (DEBUG_INTENT_MATCHING) {
6845             Log.v(TAG, "Query " + intent + ": " + results);
6846         }
6847
6848         int specificsPos = 0;
6849         int N;
6850
6851         // todo: note that the algorithm used here is O(N^2).  This
6852         // isn't a problem in our current environment, but if we start running
6853         // into situations where we have more than 5 or 10 matches then this
6854         // should probably be changed to something smarter...
6855
6856         // First we go through and resolve each of the specific items
6857         // that were supplied, taking care of removing any corresponding
6858         // duplicate items in the generic resolve list.
6859         if (specifics != null) {
6860             for (int i=0; i<specifics.length; i++) {
6861                 final Intent sintent = specifics[i];
6862                 if (sintent == null) {
6863                     continue;
6864                 }
6865
6866                 if (DEBUG_INTENT_MATCHING) {
6867                     Log.v(TAG, "Specific #" + i + ": " + sintent);
6868                 }
6869
6870                 String action = sintent.getAction();
6871                 if (resultsAction != null && resultsAction.equals(action)) {
6872                     // If this action was explicitly requested, then don't
6873                     // remove things that have it.
6874                     action = null;
6875                 }
6876
6877                 ResolveInfo ri = null;
6878                 ActivityInfo ai = null;
6879
6880                 ComponentName comp = sintent.getComponent();
6881                 if (comp == null) {
6882                     ri = resolveIntent(
6883                         sintent,
6884                         specificTypes != null ? specificTypes[i] : null,
6885                             flags, userId);
6886                     if (ri == null) {
6887                         continue;
6888                     }
6889                     if (ri == mResolveInfo) {
6890                         // ACK!  Must do something better with this.
6891                     }
6892                     ai = ri.activityInfo;
6893                     comp = new ComponentName(ai.applicationInfo.packageName,
6894                             ai.name);
6895                 } else {
6896                     ai = getActivityInfo(comp, flags, userId);
6897                     if (ai == null) {
6898                         continue;
6899                     }
6900                 }
6901
6902                 // Look for any generic query activities that are duplicates
6903                 // of this specific one, and remove them from the results.
6904                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6905                 N = results.size();
6906                 int j;
6907                 for (j=specificsPos; j<N; j++) {
6908                     ResolveInfo sri = results.get(j);
6909                     if ((sri.activityInfo.name.equals(comp.getClassName())
6910                             && sri.activityInfo.applicationInfo.packageName.equals(
6911                                     comp.getPackageName()))
6912                         || (action != null && sri.filter.matchAction(action))) {
6913                         results.remove(j);
6914                         if (DEBUG_INTENT_MATCHING) Log.v(
6915                             TAG, "Removing duplicate item from " + j
6916                             + " due to specific " + specificsPos);
6917                         if (ri == null) {
6918                             ri = sri;
6919                         }
6920                         j--;
6921                         N--;
6922                     }
6923                 }
6924
6925                 // Add this specific item to its proper place.
6926                 if (ri == null) {
6927                     ri = new ResolveInfo();
6928                     ri.activityInfo = ai;
6929                 }
6930                 results.add(specificsPos, ri);
6931                 ri.specificIndex = i;
6932                 specificsPos++;
6933             }
6934         }
6935
6936         // Now we go through the remaining generic results and remove any
6937         // duplicate actions that are found here.
6938         N = results.size();
6939         for (int i=specificsPos; i<N-1; i++) {
6940             final ResolveInfo rii = results.get(i);
6941             if (rii.filter == null) {
6942                 continue;
6943             }
6944
6945             // Iterate over all of the actions of this result's intent
6946             // filter...  typically this should be just one.
6947             final Iterator<String> it = rii.filter.actionsIterator();
6948             if (it == null) {
6949                 continue;
6950             }
6951             while (it.hasNext()) {
6952                 final String action = it.next();
6953                 if (resultsAction != null && resultsAction.equals(action)) {
6954                     // If this action was explicitly requested, then don't
6955                     // remove things that have it.
6956                     continue;
6957                 }
6958                 for (int j=i+1; j<N; j++) {
6959                     final ResolveInfo rij = results.get(j);
6960                     if (rij.filter != null && rij.filter.hasAction(action)) {
6961                         results.remove(j);
6962                         if (DEBUG_INTENT_MATCHING) Log.v(
6963                             TAG, "Removing duplicate item from " + j
6964                             + " due to action " + action + " at " + i);
6965                         j--;
6966                         N--;
6967                     }
6968                 }
6969             }
6970
6971             // If the caller didn't request filter information, drop it now
6972             // so we don't have to marshall/unmarshall it.
6973             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6974                 rii.filter = null;
6975             }
6976         }
6977
6978         // Filter out the caller activity if so requested.
6979         if (caller != null) {
6980             N = results.size();
6981             for (int i=0; i<N; i++) {
6982                 ActivityInfo ainfo = results.get(i).activityInfo;
6983                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6984                         && caller.getClassName().equals(ainfo.name)) {
6985                     results.remove(i);
6986                     break;
6987                 }
6988             }
6989         }
6990
6991         // If the caller didn't request filter information,
6992         // drop them now so we don't have to
6993         // marshall/unmarshall it.
6994         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6995             N = results.size();
6996             for (int i=0; i<N; i++) {
6997                 results.get(i).filter = null;
6998             }
6999         }
7000
7001         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7002         return results;
7003     }
7004
7005     @Override
7006     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7007             String resolvedType, int flags, int userId) {
7008         return new ParceledListSlice<>(
7009                 queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7010     }
7011
7012     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7013             String resolvedType, int flags, int userId) {
7014         if (!sUserManager.exists(userId)) return Collections.emptyList();
7015         final int callingUid = Binder.getCallingUid();
7016         flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7017                 false /*includeInstantApps*/);
7018         ComponentName comp = intent.getComponent();
7019         if (comp == null) {
7020             if (intent.getSelector() != null) {
7021                 intent = intent.getSelector();
7022                 comp = intent.getComponent();
7023             }
7024         }
7025         if (comp != null) {
7026             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7027             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7028             if (ai != null) {
7029                 ResolveInfo ri = new ResolveInfo();
7030                 ri.activityInfo = ai;
7031                 list.add(ri);
7032             }
7033             return list;
7034         }
7035
7036         // reader
7037         synchronized (mPackages) {
7038             String pkgName = intent.getPackage();
7039             if (pkgName == null) {
7040                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
7041             }
7042             final PackageParser.Package pkg = mPackages.get(pkgName);
7043             if (pkg != null) {
7044                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
7045                         userId);
7046             }
7047             return Collections.emptyList();
7048         }
7049     }
7050
7051     @Override
7052     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7053         final int callingUid = Binder.getCallingUid();
7054         return resolveServiceInternal(
7055                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7056     }
7057
7058     private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7059             int userId, int callingUid, boolean includeInstantApps) {
7060         if (!sUserManager.exists(userId)) return null;
7061         flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7062         List<ResolveInfo> query = queryIntentServicesInternal(
7063                 intent, resolvedType, flags, userId, callingUid, includeInstantApps);
7064         if (query != null) {
7065             if (query.size() >= 1) {
7066                 // If there is more than one service with the same priority,
7067                 // just arbitrarily pick the first one.
7068                 return query.get(0);
7069             }
7070         }
7071         return null;
7072     }
7073
7074     @Override
7075     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7076             String resolvedType, int flags, int userId) {
7077         final int callingUid = Binder.getCallingUid();
7078         return new ParceledListSlice<>(queryIntentServicesInternal(
7079                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7080     }
7081
7082     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7083             String resolvedType, int flags, int userId, int callingUid,
7084             boolean includeInstantApps) {
7085         if (!sUserManager.exists(userId)) return Collections.emptyList();
7086         final String instantAppPkgName = getInstantAppPackageName(callingUid);
7087         flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7088         ComponentName comp = intent.getComponent();
7089         if (comp == null) {
7090             if (intent.getSelector() != null) {
7091                 intent = intent.getSelector();
7092                 comp = intent.getComponent();
7093             }
7094         }
7095         if (comp != null) {
7096             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7097             final ServiceInfo si = getServiceInfo(comp, flags, userId);
7098             if (si != null) {
7099                 // When specifying an explicit component, we prevent the service from being
7100                 // used when either 1) the service is in an instant application and the
7101                 // caller is not the same instant application or 2) the calling package is
7102                 // ephemeral and the activity is not visible to ephemeral applications.
7103                 final boolean matchInstantApp =
7104                         (flags & PackageManager.MATCH_INSTANT) != 0;
7105                 final boolean matchVisibleToInstantAppOnly =
7106                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7107                 final boolean isCallerInstantApp =
7108                         instantAppPkgName != null;
7109                 final boolean isTargetSameInstantApp =
7110                         comp.getPackageName().equals(instantAppPkgName);
7111                 final boolean isTargetInstantApp =
7112                         (si.applicationInfo.privateFlags
7113                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7114                 final boolean isTargetHiddenFromInstantApp =
7115                         (si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7116                 final boolean blockResolution =
7117                         !isTargetSameInstantApp
7118                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7119                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7120                                         && isTargetHiddenFromInstantApp));
7121                 if (!blockResolution) {
7122                     final ResolveInfo ri = new ResolveInfo();
7123                     ri.serviceInfo = si;
7124                     list.add(ri);
7125                 }
7126             }
7127             return list;
7128         }
7129
7130         // reader
7131         synchronized (mPackages) {
7132             String pkgName = intent.getPackage();
7133             if (pkgName == null) {
7134                 return applyPostServiceResolutionFilter(
7135                         mServices.queryIntent(intent, resolvedType, flags, userId),
7136                         instantAppPkgName);
7137             }
7138             final PackageParser.Package pkg = mPackages.get(pkgName);
7139             if (pkg != null) {
7140                 return applyPostServiceResolutionFilter(
7141                         mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7142                                 userId),
7143                         instantAppPkgName);
7144             }
7145             return Collections.emptyList();
7146         }
7147     }
7148
7149     private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7150             String instantAppPkgName) {
7151         // TODO: When adding on-demand split support for non-instant apps, remove this check
7152         // and always apply post filtering
7153         if (instantAppPkgName == null) {
7154             return resolveInfos;
7155         }
7156         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7157             final ResolveInfo info = resolveInfos.get(i);
7158             final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7159             // allow services that are defined in the provided package
7160             if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7161                 if (info.serviceInfo.splitName != null
7162                         && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7163                                 info.serviceInfo.splitName)) {
7164                     // requested service is defined in a split that hasn't been installed yet.
7165                     // add the installer to the resolve list
7166                     if (DEBUG_EPHEMERAL) {
7167                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7168                     }
7169                     final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7170                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7171                             info.serviceInfo.packageName, info.serviceInfo.splitName,
7172                             info.serviceInfo.applicationInfo.versionCode);
7173                     // make sure this resolver is the default
7174                     installerInfo.isDefault = true;
7175                     installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7176                             | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7177                     // add a non-generic filter
7178                     installerInfo.filter = new IntentFilter();
7179                     // load resources from the correct package
7180                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7181                     resolveInfos.set(i, installerInfo);
7182                 }
7183                 continue;
7184             }
7185             // allow services that have been explicitly exposed to ephemeral apps
7186             if (!isEphemeralApp
7187                     && ((info.serviceInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7188                 continue;
7189             }
7190             resolveInfos.remove(i);
7191         }
7192         return resolveInfos;
7193     }
7194
7195     @Override
7196     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7197             String resolvedType, int flags, int userId) {
7198         return new ParceledListSlice<>(
7199                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7200     }
7201
7202     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7203             Intent intent, String resolvedType, int flags, int userId) {
7204         if (!sUserManager.exists(userId)) return Collections.emptyList();
7205         final int callingUid = Binder.getCallingUid();
7206         final String instantAppPkgName = getInstantAppPackageName(callingUid);
7207         flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7208                 false /*includeInstantApps*/);
7209         ComponentName comp = intent.getComponent();
7210         if (comp == null) {
7211             if (intent.getSelector() != null) {
7212                 intent = intent.getSelector();
7213                 comp = intent.getComponent();
7214             }
7215         }
7216         if (comp != null) {
7217             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7218             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7219             if (pi != null) {
7220                 // When specifying an explicit component, we prevent the provider from being
7221                 // used when either 1) the provider is in an instant application and the
7222                 // caller is not the same instant application or 2) the calling package is an
7223                 // instant application and the provider is not visible to instant applications.
7224                 final boolean matchInstantApp =
7225                         (flags & PackageManager.MATCH_INSTANT) != 0;
7226                 final boolean matchVisibleToInstantAppOnly =
7227                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7228                 final boolean isCallerInstantApp =
7229                         instantAppPkgName != null;
7230                 final boolean isTargetSameInstantApp =
7231                         comp.getPackageName().equals(instantAppPkgName);
7232                 final boolean isTargetInstantApp =
7233                         (pi.applicationInfo.privateFlags
7234                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7235                 final boolean isTargetHiddenFromInstantApp =
7236                         (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7237                 final boolean blockResolution =
7238                         !isTargetSameInstantApp
7239                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7240                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7241                                         && isTargetHiddenFromInstantApp));
7242                 if (!blockResolution) {
7243                     final ResolveInfo ri = new ResolveInfo();
7244                     ri.providerInfo = pi;
7245                     list.add(ri);
7246                 }
7247             }
7248             return list;
7249         }
7250
7251         // reader
7252         synchronized (mPackages) {
7253             String pkgName = intent.getPackage();
7254             if (pkgName == null) {
7255                 return applyPostContentProviderResolutionFilter(
7256                         mProviders.queryIntent(intent, resolvedType, flags, userId),
7257                         instantAppPkgName);
7258             }
7259             final PackageParser.Package pkg = mPackages.get(pkgName);
7260             if (pkg != null) {
7261                 return applyPostContentProviderResolutionFilter(
7262                         mProviders.queryIntentForPackage(
7263                         intent, resolvedType, flags, pkg.providers, userId),
7264                         instantAppPkgName);
7265             }
7266             return Collections.emptyList();
7267         }
7268     }
7269
7270     private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7271             List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7272         // TODO: When adding on-demand split support for non-instant applications, remove
7273         // this check and always apply post filtering
7274         if (instantAppPkgName == null) {
7275             return resolveInfos;
7276         }
7277         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7278             final ResolveInfo info = resolveInfos.get(i);
7279             final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7280             // allow providers that are defined in the provided package
7281             if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7282                 if (info.providerInfo.splitName != null
7283                         && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7284                                 info.providerInfo.splitName)) {
7285                     // requested provider is defined in a split that hasn't been installed yet.
7286                     // add the installer to the resolve list
7287                     if (DEBUG_EPHEMERAL) {
7288                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7289                     }
7290                     final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7291                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7292                             info.providerInfo.packageName, info.providerInfo.splitName,
7293                             info.providerInfo.applicationInfo.versionCode);
7294                     // make sure this resolver is the default
7295                     installerInfo.isDefault = true;
7296                     installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7297                             | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7298                     // add a non-generic filter
7299                     installerInfo.filter = new IntentFilter();
7300                     // load resources from the correct package
7301                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7302                     resolveInfos.set(i, installerInfo);
7303                 }
7304                 continue;
7305             }
7306             // allow providers that have been explicitly exposed to instant applications
7307             if (!isEphemeralApp
7308                     && ((info.providerInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7309                 continue;
7310             }
7311             resolveInfos.remove(i);
7312         }
7313         return resolveInfos;
7314     }
7315
7316     @Override
7317     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7318         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7319         flags = updateFlagsForPackage(flags, userId, null);
7320         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7321         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7322                 true /* requireFullPermission */, false /* checkShell */,
7323                 "get installed packages");
7324
7325         // writer
7326         synchronized (mPackages) {
7327             ArrayList<PackageInfo> list;
7328             if (listUninstalled) {
7329                 list = new ArrayList<>(mSettings.mPackages.size());
7330                 for (PackageSetting ps : mSettings.mPackages.values()) {
7331                     if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7332                         continue;
7333                     }
7334                     final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7335                     if (pi != null) {
7336                         list.add(pi);
7337                     }
7338                 }
7339             } else {
7340                 list = new ArrayList<>(mPackages.size());
7341                 for (PackageParser.Package p : mPackages.values()) {
7342                     if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7343                             Binder.getCallingUid(), userId)) {
7344                         continue;
7345                     }
7346                     final PackageInfo pi = generatePackageInfo((PackageSetting)
7347                             p.mExtras, flags, userId);
7348                     if (pi != null) {
7349                         list.add(pi);
7350                     }
7351                 }
7352             }
7353
7354             return new ParceledListSlice<>(list);
7355         }
7356     }
7357
7358     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7359             String[] permissions, boolean[] tmp, int flags, int userId) {
7360         int numMatch = 0;
7361         final PermissionsState permissionsState = ps.getPermissionsState();
7362         for (int i=0; i<permissions.length; i++) {
7363             final String permission = permissions[i];
7364             if (permissionsState.hasPermission(permission, userId)) {
7365                 tmp[i] = true;
7366                 numMatch++;
7367             } else {
7368                 tmp[i] = false;
7369             }
7370         }
7371         if (numMatch == 0) {
7372             return;
7373         }
7374         final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7375
7376         // The above might return null in cases of uninstalled apps or install-state
7377         // skew across users/profiles.
7378         if (pi != null) {
7379             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7380                 if (numMatch == permissions.length) {
7381                     pi.requestedPermissions = permissions;
7382                 } else {
7383                     pi.requestedPermissions = new String[numMatch];
7384                     numMatch = 0;
7385                     for (int i=0; i<permissions.length; i++) {
7386                         if (tmp[i]) {
7387                             pi.requestedPermissions[numMatch] = permissions[i];
7388                             numMatch++;
7389                         }
7390                     }
7391                 }
7392             }
7393             list.add(pi);
7394         }
7395     }
7396
7397     @Override
7398     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7399             String[] permissions, int flags, int userId) {
7400         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7401         flags = updateFlagsForPackage(flags, userId, permissions);
7402         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7403                 true /* requireFullPermission */, false /* checkShell */,
7404                 "get packages holding permissions");
7405         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7406
7407         // writer
7408         synchronized (mPackages) {
7409             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7410             boolean[] tmpBools = new boolean[permissions.length];
7411             if (listUninstalled) {
7412                 for (PackageSetting ps : mSettings.mPackages.values()) {
7413                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7414                             userId);
7415                 }
7416             } else {
7417                 for (PackageParser.Package pkg : mPackages.values()) {
7418                     PackageSetting ps = (PackageSetting)pkg.mExtras;
7419                     if (ps != null) {
7420                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7421                                 userId);
7422                     }
7423                 }
7424             }
7425
7426             return new ParceledListSlice<PackageInfo>(list);
7427         }
7428     }
7429
7430     @Override
7431     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7432         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7433         flags = updateFlagsForApplication(flags, userId, null);
7434         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7435
7436         // writer
7437         synchronized (mPackages) {
7438             ArrayList<ApplicationInfo> list;
7439             if (listUninstalled) {
7440                 list = new ArrayList<>(mSettings.mPackages.size());
7441                 for (PackageSetting ps : mSettings.mPackages.values()) {
7442                     ApplicationInfo ai;
7443                     int effectiveFlags = flags;
7444                     if (ps.isSystem()) {
7445                         effectiveFlags |= PackageManager.MATCH_ANY_USER;
7446                     }
7447                     if (ps.pkg != null) {
7448                         if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7449                             continue;
7450                         }
7451                         ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7452                                 ps.readUserState(userId), userId);
7453                         if (ai != null) {
7454                             rebaseEnabledOverlays(ai, userId);
7455                             ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7456                         }
7457                     } else {
7458                         // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7459                         // and already converts to externally visible package name
7460                         ai = generateApplicationInfoFromSettingsLPw(ps.name,
7461                                 Binder.getCallingUid(), effectiveFlags, userId);
7462                     }
7463                     if (ai != null) {
7464                         list.add(ai);
7465                     }
7466                 }
7467             } else {
7468                 list = new ArrayList<>(mPackages.size());
7469                 for (PackageParser.Package p : mPackages.values()) {
7470                     if (p.mExtras != null) {
7471                         PackageSetting ps = (PackageSetting) p.mExtras;
7472                         if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7473                             continue;
7474                         }
7475                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7476                                 ps.readUserState(userId), userId);
7477                         if (ai != null) {
7478                             rebaseEnabledOverlays(ai, userId);
7479                             ai.packageName = resolveExternalPackageNameLPr(p);
7480                             list.add(ai);
7481                         }
7482                     }
7483                 }
7484             }
7485
7486             return new ParceledListSlice<>(list);
7487         }
7488     }
7489
7490     @Override
7491     public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7492         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7493             return null;
7494         }
7495
7496         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7497                 "getEphemeralApplications");
7498         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7499                 true /* requireFullPermission */, false /* checkShell */,
7500                 "getEphemeralApplications");
7501         synchronized (mPackages) {
7502             List<InstantAppInfo> instantApps = mInstantAppRegistry
7503                     .getInstantAppsLPr(userId);
7504             if (instantApps != null) {
7505                 return new ParceledListSlice<>(instantApps);
7506             }
7507         }
7508         return null;
7509     }
7510
7511     @Override
7512     public boolean isInstantApp(String packageName, int userId) {
7513         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7514                 true /* requireFullPermission */, false /* checkShell */,
7515                 "isInstantApp");
7516         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7517             return false;
7518         }
7519         int uid = Binder.getCallingUid();
7520         if (Process.isIsolated(uid)) {
7521             uid = mIsolatedOwners.get(uid);
7522         }
7523
7524         synchronized (mPackages) {
7525             final PackageSetting ps = mSettings.mPackages.get(packageName);
7526             PackageParser.Package pkg = mPackages.get(packageName);
7527             final boolean returnAllowed =
7528                     ps != null
7529                     && (isCallerSameApp(packageName, uid)
7530                             || mContext.checkCallingOrSelfPermission(
7531                                     android.Manifest.permission.ACCESS_INSTANT_APPS)
7532                                             == PERMISSION_GRANTED
7533                             || mInstantAppRegistry.isInstantAccessGranted(
7534                                     userId, UserHandle.getAppId(uid), ps.appId));
7535             if (returnAllowed) {
7536                 return ps.getInstantApp(userId);
7537             }
7538         }
7539         return false;
7540     }
7541
7542     @Override
7543     public byte[] getInstantAppCookie(String packageName, int userId) {
7544         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7545             return null;
7546         }
7547
7548         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7549                 true /* requireFullPermission */, false /* checkShell */,
7550                 "getInstantAppCookie");
7551         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7552             return null;
7553         }
7554         synchronized (mPackages) {
7555             return mInstantAppRegistry.getInstantAppCookieLPw(
7556                     packageName, userId);
7557         }
7558     }
7559
7560     @Override
7561     public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7562         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7563             return true;
7564         }
7565
7566         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7567                 true /* requireFullPermission */, true /* checkShell */,
7568                 "setInstantAppCookie");
7569         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7570             return false;
7571         }
7572         synchronized (mPackages) {
7573             return mInstantAppRegistry.setInstantAppCookieLPw(
7574                     packageName, cookie, userId);
7575         }
7576     }
7577
7578     @Override
7579     public Bitmap getInstantAppIcon(String packageName, int userId) {
7580         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7581             return null;
7582         }
7583
7584         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7585                 "getInstantAppIcon");
7586
7587         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7588                 true /* requireFullPermission */, false /* checkShell */,
7589                 "getInstantAppIcon");
7590
7591         synchronized (mPackages) {
7592             return mInstantAppRegistry.getInstantAppIconLPw(
7593                     packageName, userId);
7594         }
7595     }
7596
7597     private boolean isCallerSameApp(String packageName, int uid) {
7598         PackageParser.Package pkg = mPackages.get(packageName);
7599         return pkg != null
7600                 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7601     }
7602
7603     @Override
7604     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7605         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7606     }
7607
7608     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7609         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7610
7611         // reader
7612         synchronized (mPackages) {
7613             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7614             final int userId = UserHandle.getCallingUserId();
7615             while (i.hasNext()) {
7616                 final PackageParser.Package p = i.next();
7617                 if (p.applicationInfo == null) continue;
7618
7619                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7620                         && !p.applicationInfo.isDirectBootAware();
7621                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7622                         && p.applicationInfo.isDirectBootAware();
7623
7624                 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7625                         && (!mSafeMode || isSystemApp(p))
7626                         && (matchesUnaware || matchesAware)) {
7627                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
7628                     if (ps != null) {
7629                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7630                                 ps.readUserState(userId), userId);
7631                         if (ai != null) {
7632                             rebaseEnabledOverlays(ai, userId);
7633                             finalList.add(ai);
7634                         }
7635                     }
7636                 }
7637             }
7638         }
7639
7640         return finalList;
7641     }
7642
7643     @Override
7644     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7645         if (!sUserManager.exists(userId)) return null;
7646         flags = updateFlagsForComponent(flags, userId, name);
7647         final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7648         // reader
7649         synchronized (mPackages) {
7650             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7651             PackageSetting ps = provider != null
7652                     ? mSettings.mPackages.get(provider.owner.packageName)
7653                     : null;
7654             if (ps != null) {
7655                 final boolean isInstantApp = ps.getInstantApp(userId);
7656                 // normal application; filter out instant application provider
7657                 if (instantAppPkgName == null && isInstantApp) {
7658                     return null;
7659                 }
7660                 // instant application; filter out other instant applications
7661                 if (instantAppPkgName != null
7662                         && isInstantApp
7663                         && !provider.owner.packageName.equals(instantAppPkgName)) {
7664                     return null;
7665                 }
7666                 // instant application; filter out non-exposed provider
7667                 if (instantAppPkgName != null
7668                         && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0) {
7669                     return null;
7670                 }
7671                 // provider not enabled
7672                 if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
7673                     return null;
7674                 }
7675                 return PackageParser.generateProviderInfo(
7676                         provider, flags, ps.readUserState(userId), userId);
7677             }
7678             return null;
7679         }
7680     }
7681
7682     /**
7683      * @deprecated
7684      */
7685     @Deprecated
7686     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7687         // reader
7688         synchronized (mPackages) {
7689             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7690                     .entrySet().iterator();
7691             final int userId = UserHandle.getCallingUserId();
7692             while (i.hasNext()) {
7693                 Map.Entry<String, PackageParser.Provider> entry = i.next();
7694                 PackageParser.Provider p = entry.getValue();
7695                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7696
7697                 if (ps != null && p.syncable
7698                         && (!mSafeMode || (p.info.applicationInfo.flags
7699                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7700                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7701                             ps.readUserState(userId), userId);
7702                     if (info != null) {
7703                         outNames.add(entry.getKey());
7704                         outInfo.add(info);
7705                     }
7706                 }
7707             }
7708         }
7709     }
7710
7711     @Override
7712     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7713             int uid, int flags, String metaDataKey) {
7714         final int userId = processName != null ? UserHandle.getUserId(uid)
7715                 : UserHandle.getCallingUserId();
7716         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7717         flags = updateFlagsForComponent(flags, userId, processName);
7718
7719         ArrayList<ProviderInfo> finalList = null;
7720         // reader
7721         synchronized (mPackages) {
7722             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
7723             while (i.hasNext()) {
7724                 final PackageParser.Provider p = i.next();
7725                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7726                 if (ps != null && p.info.authority != null
7727                         && (processName == null
7728                                 || (p.info.processName.equals(processName)
7729                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
7730                         && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
7731
7732                     // See PM.queryContentProviders()'s javadoc for why we have the metaData
7733                     // parameter.
7734                     if (metaDataKey != null
7735                             && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
7736                         continue;
7737                     }
7738
7739                     if (finalList == null) {
7740                         finalList = new ArrayList<ProviderInfo>(3);
7741                     }
7742                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
7743                             ps.readUserState(userId), userId);
7744                     if (info != null) {
7745                         finalList.add(info);
7746                     }
7747                 }
7748             }
7749         }
7750
7751         if (finalList != null) {
7752             Collections.sort(finalList, mProviderInitOrderSorter);
7753             return new ParceledListSlice<ProviderInfo>(finalList);
7754         }
7755
7756         return ParceledListSlice.emptyList();
7757     }
7758
7759     @Override
7760     public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
7761         // reader
7762         synchronized (mPackages) {
7763             final PackageParser.Instrumentation i = mInstrumentation.get(name);
7764             return PackageParser.generateInstrumentationInfo(i, flags);
7765         }
7766     }
7767
7768     @Override
7769     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
7770             String targetPackage, int flags) {
7771         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
7772     }
7773
7774     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
7775             int flags) {
7776         ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
7777
7778         // reader
7779         synchronized (mPackages) {
7780             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
7781             while (i.hasNext()) {
7782                 final PackageParser.Instrumentation p = i.next();
7783                 if (targetPackage == null
7784                         || targetPackage.equals(p.info.targetPackage)) {
7785                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
7786                             flags);
7787                     if (ii != null) {
7788                         finalList.add(ii);
7789                     }
7790                 }
7791             }
7792         }
7793
7794         return finalList;
7795     }
7796
7797     private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
7798         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
7799         try {
7800             scanDirLI(dir, parseFlags, scanFlags, currentTime);
7801         } finally {
7802             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7803         }
7804     }
7805
7806     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
7807         final File[] files = dir.listFiles();
7808         if (ArrayUtils.isEmpty(files)) {
7809             Log.d(TAG, "No files in app dir " + dir);
7810             return;
7811         }
7812
7813         if (DEBUG_PACKAGE_SCANNING) {
7814             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
7815                     + " flags=0x" + Integer.toHexString(parseFlags));
7816         }
7817         ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
7818                 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
7819
7820         // Submit files for parsing in parallel
7821         int fileCount = 0;
7822         for (File file : files) {
7823             final boolean isPackage = (isApkFile(file) || file.isDirectory())
7824                     && !PackageInstallerService.isStageName(file.getName());
7825             if (!isPackage) {
7826                 // Ignore entries which are not packages
7827                 continue;
7828             }
7829             parallelPackageParser.submit(file, parseFlags);
7830             fileCount++;
7831         }
7832
7833         // Process results one by one
7834         for (; fileCount > 0; fileCount--) {
7835             ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
7836             Throwable throwable = parseResult.throwable;
7837             int errorCode = PackageManager.INSTALL_SUCCEEDED;
7838
7839             if (throwable == null) {
7840                 // Static shared libraries have synthetic package names
7841                 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
7842                     renameStaticSharedLibraryPackage(parseResult.pkg);
7843                 }
7844                 try {
7845                     if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
7846                         scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
7847                                 currentTime, null);
7848                     }
7849                 } catch (PackageManagerException e) {
7850                     errorCode = e.error;
7851                     Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
7852                 }
7853             } else if (throwable instanceof PackageParser.PackageParserException) {
7854                 PackageParser.PackageParserException e = (PackageParser.PackageParserException)
7855                         throwable;
7856                 errorCode = e.error;
7857                 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
7858             } else {
7859                 throw new IllegalStateException("Unexpected exception occurred while parsing "
7860                         + parseResult.scanFile, throwable);
7861             }
7862
7863             // Delete invalid userdata apps
7864             if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
7865                     errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
7866                 logCriticalInfo(Log.WARN,
7867                         "Deleting invalid package at " + parseResult.scanFile);
7868                 removeCodePathLI(parseResult.scanFile);
7869             }
7870         }
7871         parallelPackageParser.close();
7872     }
7873
7874     private static File getSettingsProblemFile() {
7875         File dataDir = Environment.getDataDirectory();
7876         File systemDir = new File(dataDir, "system");
7877         File fname = new File(systemDir, "uiderrors.txt");
7878         return fname;
7879     }
7880
7881     static void reportSettingsProblem(int priority, String msg) {
7882         logCriticalInfo(priority, msg);
7883     }
7884
7885     public static void logCriticalInfo(int priority, String msg) {
7886         Slog.println(priority, TAG, msg);
7887         EventLogTags.writePmCriticalInfo(msg);
7888         try {
7889             File fname = getSettingsProblemFile();
7890             FileOutputStream out = new FileOutputStream(fname, true);
7891             PrintWriter pw = new FastPrintWriter(out);
7892             SimpleDateFormat formatter = new SimpleDateFormat();
7893             String dateString = formatter.format(new Date(System.currentTimeMillis()));
7894             pw.println(dateString + ": " + msg);
7895             pw.close();
7896             FileUtils.setPermissions(
7897                     fname.toString(),
7898                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
7899                     -1, -1);
7900         } catch (java.io.IOException e) {
7901         }
7902     }
7903
7904     private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
7905         if (srcFile.isDirectory()) {
7906             final File baseFile = new File(pkg.baseCodePath);
7907             long maxModifiedTime = baseFile.lastModified();
7908             if (pkg.splitCodePaths != null) {
7909                 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
7910                     final File splitFile = new File(pkg.splitCodePaths[i]);
7911                     maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
7912                 }
7913             }
7914             return maxModifiedTime;
7915         }
7916         return srcFile.lastModified();
7917     }
7918
7919     private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
7920             final int policyFlags) throws PackageManagerException {
7921         // When upgrading from pre-N MR1, verify the package time stamp using the package
7922         // directory and not the APK file.
7923         final long lastModifiedTime = mIsPreNMR1Upgrade
7924                 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
7925         if (ps != null
7926                 && ps.codePath.equals(srcFile)
7927                 && ps.timeStamp == lastModifiedTime
7928                 && !isCompatSignatureUpdateNeeded(pkg)
7929                 && !isRecoverSignatureUpdateNeeded(pkg)) {
7930             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
7931             KeySetManagerService ksms = mSettings.mKeySetManagerService;
7932             ArraySet<PublicKey> signingKs;
7933             synchronized (mPackages) {
7934                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
7935             }
7936             if (ps.signatures.mSignatures != null
7937                     && ps.signatures.mSignatures.length != 0
7938                     && signingKs != null) {
7939                 // Optimization: reuse the existing cached certificates
7940                 // if the package appears to be unchanged.
7941                 pkg.mSignatures = ps.signatures.mSignatures;
7942                 pkg.mSigningKeys = signingKs;
7943                 return;
7944             }
7945
7946             Slog.w(TAG, "PackageSetting for " + ps.name
7947                     + " is missing signatures.  Collecting certs again to recover them.");
7948         } else {
7949             Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
7950         }
7951
7952         try {
7953             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
7954             PackageParser.collectCertificates(pkg, policyFlags);
7955         } catch (PackageParserException e) {
7956             throw PackageManagerException.from(e);
7957         } finally {
7958             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7959         }
7960     }
7961
7962     /**
7963      *  Traces a package scan.
7964      *  @see #scanPackageLI(File, int, int, long, UserHandle)
7965      */
7966     private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
7967             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7968         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
7969         try {
7970             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
7971         } finally {
7972             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7973         }
7974     }
7975
7976     /**
7977      *  Scans a package and returns the newly parsed package.
7978      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
7979      */
7980     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
7981             long currentTime, UserHandle user) throws PackageManagerException {
7982         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
7983         PackageParser pp = new PackageParser();
7984         pp.setSeparateProcesses(mSeparateProcesses);
7985         pp.setOnlyCoreApps(mOnlyCore);
7986         pp.setDisplayMetrics(mMetrics);
7987         pp.setCallback(mPackageParserCallback);
7988
7989         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
7990             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
7991         }
7992
7993         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
7994         final PackageParser.Package pkg;
7995         try {
7996             pkg = pp.parsePackage(scanFile, parseFlags);
7997         } catch (PackageParserException e) {
7998             throw PackageManagerException.from(e);
7999         } finally {
8000             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8001         }
8002
8003         // Static shared libraries have synthetic package names
8004         if (pkg.applicationInfo.isStaticSharedLibrary()) {
8005             renameStaticSharedLibraryPackage(pkg);
8006         }
8007
8008         return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8009     }
8010
8011     /**
8012      *  Scans a package and returns the newly parsed package.
8013      *  @throws PackageManagerException on a parse error.
8014      */
8015     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8016             final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8017             throws PackageManagerException {
8018         // If the package has children and this is the first dive in the function
8019         // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8020         // packages (parent and children) would be successfully scanned before the
8021         // actual scan since scanning mutates internal state and we want to atomically
8022         // install the package and its children.
8023         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8024             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8025                 scanFlags |= SCAN_CHECK_ONLY;
8026             }
8027         } else {
8028             scanFlags &= ~SCAN_CHECK_ONLY;
8029         }
8030
8031         // Scan the parent
8032         PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8033                 scanFlags, currentTime, user);
8034
8035         // Scan the children
8036         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8037         for (int i = 0; i < childCount; i++) {
8038             PackageParser.Package childPackage = pkg.childPackages.get(i);
8039             scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8040                     currentTime, user);
8041         }
8042
8043
8044         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8045             return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8046         }
8047
8048         return scannedPkg;
8049     }
8050
8051     /**
8052      *  Scans a package and returns the newly parsed package.
8053      *  @throws PackageManagerException on a parse error.
8054      */
8055     private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8056             int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8057             throws PackageManagerException {
8058         PackageSetting ps = null;
8059         PackageSetting updatedPkg;
8060         // reader
8061         synchronized (mPackages) {
8062             // Look to see if we already know about this package.
8063             String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8064             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8065                 // This package has been renamed to its original name.  Let's
8066                 // use that.
8067                 ps = mSettings.getPackageLPr(oldName);
8068             }
8069             // If there was no original package, see one for the real package name.
8070             if (ps == null) {
8071                 ps = mSettings.getPackageLPr(pkg.packageName);
8072             }
8073             // Check to see if this package could be hiding/updating a system
8074             // package.  Must look for it either under the original or real
8075             // package name depending on our state.
8076             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8077             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8078
8079             // If this is a package we don't know about on the system partition, we
8080             // may need to remove disabled child packages on the system partition
8081             // or may need to not add child packages if the parent apk is updated
8082             // on the data partition and no longer defines this child package.
8083             if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8084                 // If this is a parent package for an updated system app and this system
8085                 // app got an OTA update which no longer defines some of the child packages
8086                 // we have to prune them from the disabled system packages.
8087                 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8088                 if (disabledPs != null) {
8089                     final int scannedChildCount = (pkg.childPackages != null)
8090                             ? pkg.childPackages.size() : 0;
8091                     final int disabledChildCount = disabledPs.childPackageNames != null
8092                             ? disabledPs.childPackageNames.size() : 0;
8093                     for (int i = 0; i < disabledChildCount; i++) {
8094                         String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8095                         boolean disabledPackageAvailable = false;
8096                         for (int j = 0; j < scannedChildCount; j++) {
8097                             PackageParser.Package childPkg = pkg.childPackages.get(j);
8098                             if (childPkg.packageName.equals(disabledChildPackageName)) {
8099                                 disabledPackageAvailable = true;
8100                                 break;
8101                             }
8102                          }
8103                          if (!disabledPackageAvailable) {
8104                              mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8105                          }
8106                     }
8107                 }
8108             }
8109         }
8110
8111         boolean updatedPkgBetter = false;
8112         // First check if this is a system package that may involve an update
8113         if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8114             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8115             // it needs to drop FLAG_PRIVILEGED.
8116             if (locationIsPrivileged(scanFile)) {
8117                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8118             } else {
8119                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8120             }
8121
8122             if (ps != null && !ps.codePath.equals(scanFile)) {
8123                 // The path has changed from what was last scanned...  check the
8124                 // version of the new path against what we have stored to determine
8125                 // what to do.
8126                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8127                 if (pkg.mVersionCode <= ps.versionCode) {
8128                     // The system package has been updated and the code path does not match
8129                     // Ignore entry. Skip it.
8130                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8131                             + " ignored: updated version " + ps.versionCode
8132                             + " better than this " + pkg.mVersionCode);
8133                     if (!updatedPkg.codePath.equals(scanFile)) {
8134                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8135                                 + ps.name + " changing from " + updatedPkg.codePathString
8136                                 + " to " + scanFile);
8137                         updatedPkg.codePath = scanFile;
8138                         updatedPkg.codePathString = scanFile.toString();
8139                         updatedPkg.resourcePath = scanFile;
8140                         updatedPkg.resourcePathString = scanFile.toString();
8141                     }
8142                     updatedPkg.pkg = pkg;
8143                     updatedPkg.versionCode = pkg.mVersionCode;
8144
8145                     // Update the disabled system child packages to point to the package too.
8146                     final int childCount = updatedPkg.childPackageNames != null
8147                             ? updatedPkg.childPackageNames.size() : 0;
8148                     for (int i = 0; i < childCount; i++) {
8149                         String childPackageName = updatedPkg.childPackageNames.get(i);
8150                         PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8151                                 childPackageName);
8152                         if (updatedChildPkg != null) {
8153                             updatedChildPkg.pkg = pkg;
8154                             updatedChildPkg.versionCode = pkg.mVersionCode;
8155                         }
8156                     }
8157
8158                     throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8159                             + scanFile + " ignored: updated version " + ps.versionCode
8160                             + " better than this " + pkg.mVersionCode);
8161                 } else {
8162                     // The current app on the system partition is better than
8163                     // what we have updated to on the data partition; switch
8164                     // back to the system partition version.
8165                     // At this point, its safely assumed that package installation for
8166                     // apps in system partition will go through. If not there won't be a working
8167                     // version of the app
8168                     // writer
8169                     synchronized (mPackages) {
8170                         // Just remove the loaded entries from package lists.
8171                         mPackages.remove(ps.name);
8172                     }
8173
8174                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8175                             + " reverting from " + ps.codePathString
8176                             + ": new version " + pkg.mVersionCode
8177                             + " better than installed " + ps.versionCode);
8178
8179                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8180                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8181                     synchronized (mInstallLock) {
8182                         args.cleanUpResourcesLI();
8183                     }
8184                     synchronized (mPackages) {
8185                         mSettings.enableSystemPackageLPw(ps.name);
8186                     }
8187                     updatedPkgBetter = true;
8188                 }
8189             }
8190         }
8191
8192         if (updatedPkg != null) {
8193             // An updated system app will not have the PARSE_IS_SYSTEM flag set
8194             // initially
8195             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8196
8197             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8198             // flag set initially
8199             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8200                 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8201             }
8202         }
8203
8204         // Verify certificates against what was last scanned
8205         collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8206
8207         /*
8208          * A new system app appeared, but we already had a non-system one of the
8209          * same name installed earlier.
8210          */
8211         boolean shouldHideSystemApp = false;
8212         if (updatedPkg == null && ps != null
8213                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8214             /*
8215              * Check to make sure the signatures match first. If they don't,
8216              * wipe the installed application and its data.
8217              */
8218             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8219                     != PackageManager.SIGNATURE_MATCH) {
8220                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8221                         + " signatures don't match existing userdata copy; removing");
8222                 try (PackageFreezer freezer = freezePackage(pkg.packageName,
8223                         "scanPackageInternalLI")) {
8224                     deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8225                 }
8226                 ps = null;
8227             } else {
8228                 /*
8229                  * If the newly-added system app is an older version than the
8230                  * already installed version, hide it. It will be scanned later
8231                  * and re-added like an update.
8232                  */
8233                 if (pkg.mVersionCode <= ps.versionCode) {
8234                     shouldHideSystemApp = true;
8235                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8236                             + " but new version " + pkg.mVersionCode + " better than installed "
8237                             + ps.versionCode + "; hiding system");
8238                 } else {
8239                     /*
8240                      * The newly found system app is a newer version that the
8241                      * one previously installed. Simply remove the
8242                      * already-installed application and replace it with our own
8243                      * while keeping the application data.
8244                      */
8245                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8246                             + " reverting from " + ps.codePathString + ": new version "
8247                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
8248                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8249                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8250                     synchronized (mInstallLock) {
8251                         args.cleanUpResourcesLI();
8252                     }
8253                 }
8254             }
8255         }
8256
8257         // The apk is forward locked (not public) if its code and resources
8258         // are kept in different files. (except for app in either system or
8259         // vendor path).
8260         // TODO grab this value from PackageSettings
8261         if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8262             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8263                 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8264             }
8265         }
8266
8267         // TODO: extend to support forward-locked splits
8268         String resourcePath = null;
8269         String baseResourcePath = null;
8270         if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8271             if (ps != null && ps.resourcePathString != null) {
8272                 resourcePath = ps.resourcePathString;
8273                 baseResourcePath = ps.resourcePathString;
8274             } else {
8275                 // Should not happen at all. Just log an error.
8276                 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8277             }
8278         } else {
8279             resourcePath = pkg.codePath;
8280             baseResourcePath = pkg.baseCodePath;
8281         }
8282
8283         // Set application objects path explicitly.
8284         pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8285         pkg.setApplicationInfoCodePath(pkg.codePath);
8286         pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8287         pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8288         pkg.setApplicationInfoResourcePath(resourcePath);
8289         pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8290         pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8291
8292         final int userId = ((user == null) ? 0 : user.getIdentifier());
8293         if (ps != null && ps.getInstantApp(userId)) {
8294             scanFlags |= SCAN_AS_INSTANT_APP;
8295         }
8296
8297         // Note that we invoke the following method only if we are about to unpack an application
8298         PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8299                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
8300
8301         /*
8302          * If the system app should be overridden by a previously installed
8303          * data, hide the system app now and let the /data/app scan pick it up
8304          * again.
8305          */
8306         if (shouldHideSystemApp) {
8307             synchronized (mPackages) {
8308                 mSettings.disableSystemPackageLPw(pkg.packageName, true);
8309             }
8310         }
8311
8312         return scannedPkg;
8313     }
8314
8315     private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8316         // Derive the new package synthetic package name
8317         pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8318                 + pkg.staticSharedLibVersion);
8319     }
8320
8321     private static String fixProcessName(String defProcessName,
8322             String processName) {
8323         if (processName == null) {
8324             return defProcessName;
8325         }
8326         return processName;
8327     }
8328
8329     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8330             throws PackageManagerException {
8331         if (pkgSetting.signatures.mSignatures != null) {
8332             // Already existing package. Make sure signatures match
8333             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8334                     == PackageManager.SIGNATURE_MATCH;
8335             if (!match) {
8336                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8337                         == PackageManager.SIGNATURE_MATCH;
8338             }
8339             if (!match) {
8340                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8341                         == PackageManager.SIGNATURE_MATCH;
8342             }
8343             if (!match) {
8344                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8345                         + pkg.packageName + " signatures do not match the "
8346                         + "previously installed version; ignoring!");
8347             }
8348         }
8349
8350         // Check for shared user signatures
8351         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8352             // Already existing package. Make sure signatures match
8353             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8354                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8355             if (!match) {
8356                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8357                         == PackageManager.SIGNATURE_MATCH;
8358             }
8359             if (!match) {
8360                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8361                         == PackageManager.SIGNATURE_MATCH;
8362             }
8363             if (!match) {
8364                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8365                         "Package " + pkg.packageName
8366                         + " has no signatures that match those in shared user "
8367                         + pkgSetting.sharedUser.name + "; ignoring!");
8368             }
8369         }
8370     }
8371
8372     /**
8373      * Enforces that only the system UID or root's UID can call a method exposed
8374      * via Binder.
8375      *
8376      * @param message used as message if SecurityException is thrown
8377      * @throws SecurityException if the caller is not system or root
8378      */
8379     private static final void enforceSystemOrRoot(String message) {
8380         final int uid = Binder.getCallingUid();
8381         if (uid != Process.SYSTEM_UID && uid != 0) {
8382             throw new SecurityException(message);
8383         }
8384     }
8385
8386     @Override
8387     public void performFstrimIfNeeded() {
8388         enforceSystemOrRoot("Only the system can request fstrim");
8389
8390         // Before everything else, see whether we need to fstrim.
8391         try {
8392             IStorageManager sm = PackageHelper.getStorageManager();
8393             if (sm != null) {
8394                 boolean doTrim = false;
8395                 final long interval = android.provider.Settings.Global.getLong(
8396                         mContext.getContentResolver(),
8397                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8398                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8399                 if (interval > 0) {
8400                     final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8401                     if (timeSinceLast > interval) {
8402                         doTrim = true;
8403                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8404                                 + "; running immediately");
8405                     }
8406                 }
8407                 if (doTrim) {
8408                     final boolean dexOptDialogShown;
8409                     synchronized (mPackages) {
8410                         dexOptDialogShown = mDexOptDialogShown;
8411                     }
8412                     if (!isFirstBoot() && dexOptDialogShown) {
8413                         try {
8414                             ActivityManager.getService().showBootMessage(
8415                                     mContext.getResources().getString(
8416                                             R.string.android_upgrading_fstrim), true);
8417                         } catch (RemoteException e) {
8418                         }
8419                     }
8420                     sm.runMaintenance();
8421                 }
8422             } else {
8423                 Slog.e(TAG, "storageManager service unavailable!");
8424             }
8425         } catch (RemoteException e) {
8426             // Can't happen; StorageManagerService is local
8427         }
8428     }
8429
8430     @Override
8431     public void updatePackagesIfNeeded() {
8432         enforceSystemOrRoot("Only the system can request package update");
8433
8434         // We need to re-extract after an OTA.
8435         boolean causeUpgrade = isUpgrade();
8436
8437         // First boot or factory reset.
8438         // Note: we also handle devices that are upgrading to N right now as if it is their
8439         //       first boot, as they do not have profile data.
8440         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8441
8442         // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8443         boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8444
8445         if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8446             return;
8447         }
8448
8449         List<PackageParser.Package> pkgs;
8450         synchronized (mPackages) {
8451             pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8452         }
8453
8454         final long startTime = System.nanoTime();
8455         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8456                     getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8457
8458         final int elapsedTimeSeconds =
8459                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8460
8461         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8462         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8463         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8464         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8465         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8466     }
8467
8468     /**
8469      * Performs dexopt on the set of packages in {@code packages} and returns an int array
8470      * containing statistics about the invocation. The array consists of three elements,
8471      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8472      * and {@code numberOfPackagesFailed}.
8473      */
8474     private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8475             String compilerFilter) {
8476
8477         int numberOfPackagesVisited = 0;
8478         int numberOfPackagesOptimized = 0;
8479         int numberOfPackagesSkipped = 0;
8480         int numberOfPackagesFailed = 0;
8481         final int numberOfPackagesToDexopt = pkgs.size();
8482
8483         for (PackageParser.Package pkg : pkgs) {
8484             numberOfPackagesVisited++;
8485
8486             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8487                 if (DEBUG_DEXOPT) {
8488                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8489                 }
8490                 numberOfPackagesSkipped++;
8491                 continue;
8492             }
8493
8494             if (DEBUG_DEXOPT) {
8495                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8496                         numberOfPackagesToDexopt + ": " + pkg.packageName);
8497             }
8498
8499             if (showDialog) {
8500                 try {
8501                     ActivityManager.getService().showBootMessage(
8502                             mContext.getResources().getString(R.string.android_upgrading_apk,
8503                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8504                 } catch (RemoteException e) {
8505                 }
8506                 synchronized (mPackages) {
8507                     mDexOptDialogShown = true;
8508                 }
8509             }
8510
8511             // If the OTA updates a system app which was previously preopted to a non-preopted state
8512             // the app might end up being verified at runtime. That's because by default the apps
8513             // are verify-profile but for preopted apps there's no profile.
8514             // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8515             // that before the OTA the app was preopted) the app gets compiled with a non-profile
8516             // filter (by default interpret-only).
8517             // Note that at this stage unused apps are already filtered.
8518             if (isSystemApp(pkg) &&
8519                     DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8520                     !Environment.getReferenceProfile(pkg.packageName).exists()) {
8521                 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8522             }
8523
8524             // checkProfiles is false to avoid merging profiles during boot which
8525             // might interfere with background compilation (b/28612421).
8526             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8527             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8528             // trade-off worth doing to save boot time work.
8529             int dexOptStatus = performDexOptTraced(pkg.packageName,
8530                     false /* checkProfiles */,
8531                     compilerFilter,
8532                     false /* force */);
8533             switch (dexOptStatus) {
8534                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
8535                     numberOfPackagesOptimized++;
8536                     break;
8537                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
8538                     numberOfPackagesSkipped++;
8539                     break;
8540                 case PackageDexOptimizer.DEX_OPT_FAILED:
8541                     numberOfPackagesFailed++;
8542                     break;
8543                 default:
8544                     Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8545                     break;
8546             }
8547         }
8548
8549         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8550                 numberOfPackagesFailed };
8551     }
8552
8553     @Override
8554     public void notifyPackageUse(String packageName, int reason) {
8555         synchronized (mPackages) {
8556             PackageParser.Package p = mPackages.get(packageName);
8557             if (p == null) {
8558                 return;
8559             }
8560             p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8561         }
8562     }
8563
8564     @Override
8565     public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8566         int userId = UserHandle.getCallingUserId();
8567         ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8568         if (ai == null) {
8569             Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8570                 + loadingPackageName + ", user=" + userId);
8571             return;
8572         }
8573         mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8574     }
8575
8576     // TODO: this is not used nor needed. Delete it.
8577     @Override
8578     public boolean performDexOptIfNeeded(String packageName) {
8579         int dexOptStatus = performDexOptTraced(packageName,
8580                 false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
8581         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8582     }
8583
8584     @Override
8585     public boolean performDexOpt(String packageName,
8586             boolean checkProfiles, int compileReason, boolean force) {
8587         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8588                 getCompilerFilterForReason(compileReason), force);
8589         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8590     }
8591
8592     @Override
8593     public boolean performDexOptMode(String packageName,
8594             boolean checkProfiles, String targetCompilerFilter, boolean force) {
8595         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8596                 targetCompilerFilter, force);
8597         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8598     }
8599
8600     private int performDexOptTraced(String packageName,
8601                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8602         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8603         try {
8604             return performDexOptInternal(packageName, checkProfiles,
8605                     targetCompilerFilter, force);
8606         } finally {
8607             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8608         }
8609     }
8610
8611     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8612     // if the package can now be considered up to date for the given filter.
8613     private int performDexOptInternal(String packageName,
8614                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
8615         PackageParser.Package p;
8616         synchronized (mPackages) {
8617             p = mPackages.get(packageName);
8618             if (p == null) {
8619                 // Package could not be found. Report failure.
8620                 return PackageDexOptimizer.DEX_OPT_FAILED;
8621             }
8622             mPackageUsage.maybeWriteAsync(mPackages);
8623             mCompilerStats.maybeWriteAsync();
8624         }
8625         long callingId = Binder.clearCallingIdentity();
8626         try {
8627             synchronized (mInstallLock) {
8628                 return performDexOptInternalWithDependenciesLI(p, checkProfiles,
8629                         targetCompilerFilter, force);
8630             }
8631         } finally {
8632             Binder.restoreCallingIdentity(callingId);
8633         }
8634     }
8635
8636     public ArraySet<String> getOptimizablePackages() {
8637         ArraySet<String> pkgs = new ArraySet<String>();
8638         synchronized (mPackages) {
8639             for (PackageParser.Package p : mPackages.values()) {
8640                 if (PackageDexOptimizer.canOptimizePackage(p)) {
8641                     pkgs.add(p.packageName);
8642                 }
8643             }
8644         }
8645         return pkgs;
8646     }
8647
8648     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8649             boolean checkProfiles, String targetCompilerFilter,
8650             boolean force) {
8651         // Select the dex optimizer based on the force parameter.
8652         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8653         //       allocate an object here.
8654         PackageDexOptimizer pdo = force
8655                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8656                 : mPackageDexOptimizer;
8657
8658         // Dexopt all dependencies first. Note: we ignore the return value and march on
8659         // on errors.
8660         // Note that we are going to call performDexOpt on those libraries as many times as
8661         // they are referenced in packages. When we do a batch of performDexOpt (for example
8662         // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
8663         // and the first package that uses the library will dexopt it. The
8664         // others will see that the compiled code for the library is up to date.
8665         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
8666         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
8667         if (!deps.isEmpty()) {
8668             for (PackageParser.Package depPackage : deps) {
8669                 // TODO: Analyze and investigate if we (should) profile libraries.
8670                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
8671                         false /* checkProfiles */,
8672                         targetCompilerFilter,
8673                         getOrCreateCompilerPackageStats(depPackage),
8674                         true /* isUsedByOtherApps */);
8675             }
8676         }
8677         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
8678                 targetCompilerFilter, getOrCreateCompilerPackageStats(p),
8679                 mDexManager.isUsedByOtherApps(p.packageName));
8680     }
8681
8682     // Performs dexopt on the used secondary dex files belonging to the given package.
8683     // Returns true if all dex files were process successfully (which could mean either dexopt or
8684     // skip). Returns false if any of the files caused errors.
8685     @Override
8686     public boolean performDexOptSecondary(String packageName, String compilerFilter,
8687             boolean force) {
8688         mDexManager.reconcileSecondaryDexFiles(packageName);
8689         return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
8690     }
8691
8692     public boolean performDexOptSecondary(String packageName, int compileReason,
8693             boolean force) {
8694         return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
8695     }
8696
8697     /**
8698      * Reconcile the information we have about the secondary dex files belonging to
8699      * {@code packagName} and the actual dex files. For all dex files that were
8700      * deleted, update the internal records and delete the generated oat files.
8701      */
8702     @Override
8703     public void reconcileSecondaryDexFiles(String packageName) {
8704         mDexManager.reconcileSecondaryDexFiles(packageName);
8705     }
8706
8707     // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
8708     // a reference there.
8709     /*package*/ DexManager getDexManager() {
8710         return mDexManager;
8711     }
8712
8713     /**
8714      * Execute the background dexopt job immediately.
8715      */
8716     @Override
8717     public boolean runBackgroundDexoptJob() {
8718         return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
8719     }
8720
8721     List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
8722         if (p.usesLibraries != null || p.usesOptionalLibraries != null
8723                 || p.usesStaticLibraries != null) {
8724             ArrayList<PackageParser.Package> retValue = new ArrayList<>();
8725             Set<String> collectedNames = new HashSet<>();
8726             findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
8727
8728             retValue.remove(p);
8729
8730             return retValue;
8731         } else {
8732             return Collections.emptyList();
8733         }
8734     }
8735
8736     private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
8737             ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8738         if (!collectedNames.contains(p.packageName)) {
8739             collectedNames.add(p.packageName);
8740             collected.add(p);
8741
8742             if (p.usesLibraries != null) {
8743                 findSharedNonSystemLibrariesRecursive(p.usesLibraries,
8744                         null, collected, collectedNames);
8745             }
8746             if (p.usesOptionalLibraries != null) {
8747                 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
8748                         null, collected, collectedNames);
8749             }
8750             if (p.usesStaticLibraries != null) {
8751                 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
8752                         p.usesStaticLibrariesVersions, collected, collectedNames);
8753             }
8754         }
8755     }
8756
8757     private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
8758             ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8759         final int libNameCount = libs.size();
8760         for (int i = 0; i < libNameCount; i++) {
8761             String libName = libs.get(i);
8762             int version = (versions != null && versions.length == libNameCount)
8763                     ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
8764             PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
8765             if (libPkg != null) {
8766                 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
8767             }
8768         }
8769     }
8770
8771     private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
8772         synchronized (mPackages) {
8773             SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
8774             if (libEntry != null) {
8775                 return mPackages.get(libEntry.apk);
8776             }
8777             return null;
8778         }
8779     }
8780
8781     private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
8782         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
8783         if (versionedLib == null) {
8784             return null;
8785         }
8786         return versionedLib.get(version);
8787     }
8788
8789     private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
8790         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
8791                 pkg.staticSharedLibName);
8792         if (versionedLib == null) {
8793             return null;
8794         }
8795         int previousLibVersion = -1;
8796         final int versionCount = versionedLib.size();
8797         for (int i = 0; i < versionCount; i++) {
8798             final int libVersion = versionedLib.keyAt(i);
8799             if (libVersion < pkg.staticSharedLibVersion) {
8800                 previousLibVersion = Math.max(previousLibVersion, libVersion);
8801             }
8802         }
8803         if (previousLibVersion >= 0) {
8804             return versionedLib.get(previousLibVersion);
8805         }
8806         return null;
8807     }
8808
8809     public void shutdown() {
8810         mPackageUsage.writeNow(mPackages);
8811         mCompilerStats.writeNow();
8812     }
8813
8814     @Override
8815     public void dumpProfiles(String packageName) {
8816         PackageParser.Package pkg;
8817         synchronized (mPackages) {
8818             pkg = mPackages.get(packageName);
8819             if (pkg == null) {
8820                 throw new IllegalArgumentException("Unknown package: " + packageName);
8821             }
8822         }
8823         /* Only the shell, root, or the app user should be able to dump profiles. */
8824         int callingUid = Binder.getCallingUid();
8825         if (callingUid != Process.SHELL_UID &&
8826             callingUid != Process.ROOT_UID &&
8827             callingUid != pkg.applicationInfo.uid) {
8828             throw new SecurityException("dumpProfiles");
8829         }
8830
8831         synchronized (mInstallLock) {
8832             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
8833             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
8834             try {
8835                 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
8836                 String codePaths = TextUtils.join(";", allCodePaths);
8837                 mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
8838             } catch (InstallerException e) {
8839                 Slog.w(TAG, "Failed to dump profiles", e);
8840             }
8841             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8842         }
8843     }
8844
8845     @Override
8846     public void forceDexOpt(String packageName) {
8847         enforceSystemOrRoot("forceDexOpt");
8848
8849         PackageParser.Package pkg;
8850         synchronized (mPackages) {
8851             pkg = mPackages.get(packageName);
8852             if (pkg == null) {
8853                 throw new IllegalArgumentException("Unknown package: " + packageName);
8854             }
8855         }
8856
8857         synchronized (mInstallLock) {
8858             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8859
8860             // Whoever is calling forceDexOpt wants a fully compiled package.
8861             // Don't use profiles since that may cause compilation to be skipped.
8862             final int res = performDexOptInternalWithDependenciesLI(pkg,
8863                     false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
8864                     true /* force */);
8865
8866             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8867             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
8868                 throw new IllegalStateException("Failed to dexopt: " + res);
8869             }
8870         }
8871     }
8872
8873     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
8874         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8875             Slog.w(TAG, "Unable to update from " + oldPkg.name
8876                     + " to " + newPkg.packageName
8877                     + ": old package not in system partition");
8878             return false;
8879         } else if (mPackages.get(oldPkg.name) != null) {
8880             Slog.w(TAG, "Unable to update from " + oldPkg.name
8881                     + " to " + newPkg.packageName
8882                     + ": old package still exists");
8883             return false;
8884         }
8885         return true;
8886     }
8887
8888     void removeCodePathLI(File codePath) {
8889         if (codePath.isDirectory()) {
8890             try {
8891                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
8892             } catch (InstallerException e) {
8893                 Slog.w(TAG, "Failed to remove code path", e);
8894             }
8895         } else {
8896             codePath.delete();
8897         }
8898     }
8899
8900     private int[] resolveUserIds(int userId) {
8901         return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
8902     }
8903
8904     private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8905         if (pkg == null) {
8906             Slog.wtf(TAG, "Package was null!", new Throwable());
8907             return;
8908         }
8909         clearAppDataLeafLIF(pkg, userId, flags);
8910         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8911         for (int i = 0; i < childCount; i++) {
8912             clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8913         }
8914     }
8915
8916     private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8917         final PackageSetting ps;
8918         synchronized (mPackages) {
8919             ps = mSettings.mPackages.get(pkg.packageName);
8920         }
8921         for (int realUserId : resolveUserIds(userId)) {
8922             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8923             try {
8924                 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8925                         ceDataInode);
8926             } catch (InstallerException e) {
8927                 Slog.w(TAG, String.valueOf(e));
8928             }
8929         }
8930     }
8931
8932     private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8933         if (pkg == null) {
8934             Slog.wtf(TAG, "Package was null!", new Throwable());
8935             return;
8936         }
8937         destroyAppDataLeafLIF(pkg, userId, flags);
8938         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8939         for (int i = 0; i < childCount; i++) {
8940             destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8941         }
8942     }
8943
8944     private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8945         final PackageSetting ps;
8946         synchronized (mPackages) {
8947             ps = mSettings.mPackages.get(pkg.packageName);
8948         }
8949         for (int realUserId : resolveUserIds(userId)) {
8950             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8951             try {
8952                 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8953                         ceDataInode);
8954             } catch (InstallerException e) {
8955                 Slog.w(TAG, String.valueOf(e));
8956             }
8957             mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
8958         }
8959     }
8960
8961     private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
8962         if (pkg == null) {
8963             Slog.wtf(TAG, "Package was null!", new Throwable());
8964             return;
8965         }
8966         destroyAppProfilesLeafLIF(pkg);
8967         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8968         for (int i = 0; i < childCount; i++) {
8969             destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
8970         }
8971     }
8972
8973     private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
8974         try {
8975             mInstaller.destroyAppProfiles(pkg.packageName);
8976         } catch (InstallerException e) {
8977             Slog.w(TAG, String.valueOf(e));
8978         }
8979     }
8980
8981     private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
8982         if (pkg == null) {
8983             Slog.wtf(TAG, "Package was null!", new Throwable());
8984             return;
8985         }
8986         clearAppProfilesLeafLIF(pkg);
8987         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8988         for (int i = 0; i < childCount; i++) {
8989             clearAppProfilesLeafLIF(pkg.childPackages.get(i));
8990         }
8991     }
8992
8993     private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
8994         try {
8995             mInstaller.clearAppProfiles(pkg.packageName);
8996         } catch (InstallerException e) {
8997             Slog.w(TAG, String.valueOf(e));
8998         }
8999     }
9000
9001     private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9002             long lastUpdateTime) {
9003         // Set parent install/update time
9004         PackageSetting ps = (PackageSetting) pkg.mExtras;
9005         if (ps != null) {
9006             ps.firstInstallTime = firstInstallTime;
9007             ps.lastUpdateTime = lastUpdateTime;
9008         }
9009         // Set children install/update time
9010         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9011         for (int i = 0; i < childCount; i++) {
9012             PackageParser.Package childPkg = pkg.childPackages.get(i);
9013             ps = (PackageSetting) childPkg.mExtras;
9014             if (ps != null) {
9015                 ps.firstInstallTime = firstInstallTime;
9016                 ps.lastUpdateTime = lastUpdateTime;
9017             }
9018         }
9019     }
9020
9021     private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9022             PackageParser.Package changingLib) {
9023         if (file.path != null) {
9024             usesLibraryFiles.add(file.path);
9025             return;
9026         }
9027         PackageParser.Package p = mPackages.get(file.apk);
9028         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9029             // If we are doing this while in the middle of updating a library apk,
9030             // then we need to make sure to use that new apk for determining the
9031             // dependencies here.  (We haven't yet finished committing the new apk
9032             // to the package manager state.)
9033             if (p == null || p.packageName.equals(changingLib.packageName)) {
9034                 p = changingLib;
9035             }
9036         }
9037         if (p != null) {
9038             usesLibraryFiles.addAll(p.getAllCodePaths());
9039         }
9040     }
9041
9042     private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9043             PackageParser.Package changingLib) throws PackageManagerException {
9044         if (pkg == null) {
9045             return;
9046         }
9047         ArraySet<String> usesLibraryFiles = null;
9048         if (pkg.usesLibraries != null) {
9049             usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9050                     null, null, pkg.packageName, changingLib, true, null);
9051         }
9052         if (pkg.usesStaticLibraries != null) {
9053             usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9054                     pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9055                     pkg.packageName, changingLib, true, usesLibraryFiles);
9056         }
9057         if (pkg.usesOptionalLibraries != null) {
9058             usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9059                     null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9060         }
9061         if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9062             pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9063         } else {
9064             pkg.usesLibraryFiles = null;
9065         }
9066     }
9067
9068     private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9069             @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9070             @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9071             boolean required, @Nullable ArraySet<String> outUsedLibraries)
9072             throws PackageManagerException {
9073         final int libCount = requestedLibraries.size();
9074         for (int i = 0; i < libCount; i++) {
9075             final String libName = requestedLibraries.get(i);
9076             final int libVersion = requiredVersions != null ? requiredVersions[i]
9077                     : SharedLibraryInfo.VERSION_UNDEFINED;
9078             final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9079             if (libEntry == null) {
9080                 if (required) {
9081                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9082                             "Package " + packageName + " requires unavailable shared library "
9083                                     + libName + "; failing!");
9084                 } else {
9085                     Slog.w(TAG, "Package " + packageName
9086                             + " desires unavailable shared library "
9087                             + libName + "; ignoring!");
9088                 }
9089             } else {
9090                 if (requiredVersions != null && requiredCertDigests != null) {
9091                     if (libEntry.info.getVersion() != requiredVersions[i]) {
9092                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9093                             "Package " + packageName + " requires unavailable static shared"
9094                                     + " library " + libName + " version "
9095                                     + libEntry.info.getVersion() + "; failing!");
9096                     }
9097
9098                     PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9099                     if (libPkg == null) {
9100                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9101                                 "Package " + packageName + " requires unavailable static shared"
9102                                         + " library; failing!");
9103                     }
9104
9105                     String expectedCertDigest = requiredCertDigests[i];
9106                     String libCertDigest = PackageUtils.computeCertSha256Digest(
9107                                 libPkg.mSignatures[0]);
9108                     if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9109                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9110                                 "Package " + packageName + " requires differently signed" +
9111                                         " static shared library; failing!");
9112                     }
9113                 }
9114
9115                 if (outUsedLibraries == null) {
9116                     outUsedLibraries = new ArraySet<>();
9117                 }
9118                 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9119             }
9120         }
9121         return outUsedLibraries;
9122     }
9123
9124     private static boolean hasString(List<String> list, List<String> which) {
9125         if (list == null) {
9126             return false;
9127         }
9128         for (int i=list.size()-1; i>=0; i--) {
9129             for (int j=which.size()-1; j>=0; j--) {
9130                 if (which.get(j).equals(list.get(i))) {
9131                     return true;
9132                 }
9133             }
9134         }
9135         return false;
9136     }
9137
9138     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9139             PackageParser.Package changingPkg) {
9140         ArrayList<PackageParser.Package> res = null;
9141         for (PackageParser.Package pkg : mPackages.values()) {
9142             if (changingPkg != null
9143                     && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9144                     && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9145                     && !ArrayUtils.contains(pkg.usesStaticLibraries,
9146                             changingPkg.staticSharedLibName)) {
9147                 return null;
9148             }
9149             if (res == null) {
9150                 res = new ArrayList<>();
9151             }
9152             res.add(pkg);
9153             try {
9154                 updateSharedLibrariesLPr(pkg, changingPkg);
9155             } catch (PackageManagerException e) {
9156                 // If a system app update or an app and a required lib missing we
9157                 // delete the package and for updated system apps keep the data as
9158                 // it is better for the user to reinstall than to be in an limbo
9159                 // state. Also libs disappearing under an app should never happen
9160                 // - just in case.
9161                 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9162                     final int flags = pkg.isUpdatedSystemApp()
9163                             ? PackageManager.DELETE_KEEP_DATA : 0;
9164                     deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9165                             flags , null, true, null);
9166                 }
9167                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9168             }
9169         }
9170         return res;
9171     }
9172
9173     /**
9174      * Derive the value of the {@code cpuAbiOverride} based on the provided
9175      * value and an optional stored value from the package settings.
9176      */
9177     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9178         String cpuAbiOverride = null;
9179
9180         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9181             cpuAbiOverride = null;
9182         } else if (abiOverride != null) {
9183             cpuAbiOverride = abiOverride;
9184         } else if (settings != null) {
9185             cpuAbiOverride = settings.cpuAbiOverrideString;
9186         }
9187
9188         return cpuAbiOverride;
9189     }
9190
9191     private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9192             final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9193                     throws PackageManagerException {
9194         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9195         // If the package has children and this is the first dive in the function
9196         // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9197         // whether all packages (parent and children) would be successfully scanned
9198         // before the actual scan since scanning mutates internal state and we want
9199         // to atomically install the package and its children.
9200         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9201             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9202                 scanFlags |= SCAN_CHECK_ONLY;
9203             }
9204         } else {
9205             scanFlags &= ~SCAN_CHECK_ONLY;
9206         }
9207
9208         final PackageParser.Package scannedPkg;
9209         try {
9210             // Scan the parent
9211             scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9212             // Scan the children
9213             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9214             for (int i = 0; i < childCount; i++) {
9215                 PackageParser.Package childPkg = pkg.childPackages.get(i);
9216                 scanPackageLI(childPkg, policyFlags,
9217                         scanFlags, currentTime, user);
9218             }
9219         } finally {
9220             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9221         }
9222
9223         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9224             return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9225         }
9226
9227         return scannedPkg;
9228     }
9229
9230     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9231             int scanFlags, long currentTime, @Nullable UserHandle user)
9232                     throws PackageManagerException {
9233         boolean success = false;
9234         try {
9235             final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9236                     currentTime, user);
9237             success = true;
9238             return res;
9239         } finally {
9240             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9241                 // DELETE_DATA_ON_FAILURES is only used by frozen paths
9242                 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9243                         StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9244                 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9245             }
9246         }
9247     }
9248
9249     /**
9250      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9251      */
9252     private static boolean apkHasCode(String fileName) {
9253         StrictJarFile jarFile = null;
9254         try {
9255             jarFile = new StrictJarFile(fileName,
9256                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9257             return jarFile.findEntry("classes.dex") != null;
9258         } catch (IOException ignore) {
9259         } finally {
9260             try {
9261                 if (jarFile != null) {
9262                     jarFile.close();
9263                 }
9264             } catch (IOException ignore) {}
9265         }
9266         return false;
9267     }
9268
9269     /**
9270      * Enforces code policy for the package. This ensures that if an APK has
9271      * declared hasCode="true" in its manifest that the APK actually contains
9272      * code.
9273      *
9274      * @throws PackageManagerException If bytecode could not be found when it should exist
9275      */
9276     private static void assertCodePolicy(PackageParser.Package pkg)
9277             throws PackageManagerException {
9278         final boolean shouldHaveCode =
9279                 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9280         if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9281             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9282                     "Package " + pkg.baseCodePath + " code is missing");
9283         }
9284
9285         if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9286             for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9287                 final boolean splitShouldHaveCode =
9288                         (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9289                 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9290                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9291                             "Package " + pkg.splitCodePaths[i] + " code is missing");
9292                 }
9293             }
9294         }
9295     }
9296
9297     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9298             final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9299                     throws PackageManagerException {
9300         if (DEBUG_PACKAGE_SCANNING) {
9301             if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9302                 Log.d(TAG, "Scanning package " + pkg.packageName);
9303         }
9304
9305         applyPolicy(pkg, policyFlags);
9306
9307         assertPackageIsValid(pkg, policyFlags, scanFlags);
9308
9309         // Initialize package source and resource directories
9310         final File scanFile = new File(pkg.codePath);
9311         final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9312         final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9313
9314         SharedUserSetting suid = null;
9315         PackageSetting pkgSetting = null;
9316
9317         // Getting the package setting may have a side-effect, so if we
9318         // are only checking if scan would succeed, stash a copy of the
9319         // old setting to restore at the end.
9320         PackageSetting nonMutatedPs = null;
9321
9322         // We keep references to the derived CPU Abis from settings in oder to reuse
9323         // them in the case where we're not upgrading or booting for the first time.
9324         String primaryCpuAbiFromSettings = null;
9325         String secondaryCpuAbiFromSettings = null;
9326
9327         // writer
9328         synchronized (mPackages) {
9329             if (pkg.mSharedUserId != null) {
9330                 // SIDE EFFECTS; may potentially allocate a new shared user
9331                 suid = mSettings.getSharedUserLPw(
9332                         pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9333                 if (DEBUG_PACKAGE_SCANNING) {
9334                     if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9335                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9336                                 + "): packages=" + suid.packages);
9337                 }
9338             }
9339
9340             // Check if we are renaming from an original package name.
9341             PackageSetting origPackage = null;
9342             String realName = null;
9343             if (pkg.mOriginalPackages != null) {
9344                 // This package may need to be renamed to a previously
9345                 // installed name.  Let's check on that...
9346                 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9347                 if (pkg.mOriginalPackages.contains(renamed)) {
9348                     // This package had originally been installed as the
9349                     // original name, and we have already taken care of
9350                     // transitioning to the new one.  Just update the new
9351                     // one to continue using the old name.
9352                     realName = pkg.mRealPackage;
9353                     if (!pkg.packageName.equals(renamed)) {
9354                         // Callers into this function may have already taken
9355                         // care of renaming the package; only do it here if
9356                         // it is not already done.
9357                         pkg.setPackageName(renamed);
9358                     }
9359                 } else {
9360                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9361                         if ((origPackage = mSettings.getPackageLPr(
9362                                 pkg.mOriginalPackages.get(i))) != null) {
9363                             // We do have the package already installed under its
9364                             // original name...  should we use it?
9365                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9366                                 // New package is not compatible with original.
9367                                 origPackage = null;
9368                                 continue;
9369                             } else if (origPackage.sharedUser != null) {
9370                                 // Make sure uid is compatible between packages.
9371                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9372                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9373                                             + " to " + pkg.packageName + ": old uid "
9374                                             + origPackage.sharedUser.name
9375                                             + " differs from " + pkg.mSharedUserId);
9376                                     origPackage = null;
9377                                     continue;
9378                                 }
9379                                 // TODO: Add case when shared user id is added [b/28144775]
9380                             } else {
9381                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9382                                         + pkg.packageName + " to old name " + origPackage.name);
9383                             }
9384                             break;
9385                         }
9386                     }
9387                 }
9388             }
9389
9390             if (mTransferedPackages.contains(pkg.packageName)) {
9391                 Slog.w(TAG, "Package " + pkg.packageName
9392                         + " was transferred to another, but its .apk remains");
9393             }
9394
9395             // See comments in nonMutatedPs declaration
9396             if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9397                 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9398                 if (foundPs != null) {
9399                     nonMutatedPs = new PackageSetting(foundPs);
9400                 }
9401             }
9402
9403             if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9404                 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9405                 if (foundPs != null) {
9406                     primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9407                     secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9408                 }
9409             }
9410
9411             pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9412             if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9413                 PackageManagerService.reportSettingsProblem(Log.WARN,
9414                         "Package " + pkg.packageName + " shared user changed from "
9415                                 + (pkgSetting.sharedUser != null
9416                                         ? pkgSetting.sharedUser.name : "<nothing>")
9417                                 + " to "
9418                                 + (suid != null ? suid.name : "<nothing>")
9419                                 + "; replacing with new");
9420                 pkgSetting = null;
9421             }
9422             final PackageSetting oldPkgSetting =
9423                     pkgSetting == null ? null : new PackageSetting(pkgSetting);
9424             final PackageSetting disabledPkgSetting =
9425                     mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9426
9427             String[] usesStaticLibraries = null;
9428             if (pkg.usesStaticLibraries != null) {
9429                 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9430                 pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9431             }
9432
9433             if (pkgSetting == null) {
9434                 final String parentPackageName = (pkg.parentPackage != null)
9435                         ? pkg.parentPackage.packageName : null;
9436                 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9437                 // REMOVE SharedUserSetting from method; update in a separate call
9438                 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9439                         disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9440                         pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9441                         pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9442                         pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9443                         true /*allowInstall*/, instantApp, parentPackageName,
9444                         pkg.getChildPackageNames(), UserManagerService.getInstance(),
9445                         usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9446                 // SIDE EFFECTS; updates system state; move elsewhere
9447                 if (origPackage != null) {
9448                     mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9449                 }
9450                 mSettings.addUserToSettingLPw(pkgSetting);
9451             } else {
9452                 // REMOVE SharedUserSetting from method; update in a separate call.
9453                 //
9454                 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9455                 // secondaryCpuAbi are not known at this point so we always update them
9456                 // to null here, only to reset them at a later point.
9457                 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9458                         pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9459                         pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9460                         pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9461                         UserManagerService.getInstance(), usesStaticLibraries,
9462                         pkg.usesStaticLibrariesVersions);
9463             }
9464             // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9465             mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9466
9467             // SIDE EFFECTS; modifies system state; move elsewhere
9468             if (pkgSetting.origPackage != null) {
9469                 // If we are first transitioning from an original package,
9470                 // fix up the new package's name now.  We need to do this after
9471                 // looking up the package under its new name, so getPackageLP
9472                 // can take care of fiddling things correctly.
9473                 pkg.setPackageName(origPackage.name);
9474
9475                 // File a report about this.
9476                 String msg = "New package " + pkgSetting.realName
9477                         + " renamed to replace old package " + pkgSetting.name;
9478                 reportSettingsProblem(Log.WARN, msg);
9479
9480                 // Make a note of it.
9481                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9482                     mTransferedPackages.add(origPackage.name);
9483                 }
9484
9485                 // No longer need to retain this.
9486                 pkgSetting.origPackage = null;
9487             }
9488
9489             // SIDE EFFECTS; modifies system state; move elsewhere
9490             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9491                 // Make a note of it.
9492                 mTransferedPackages.add(pkg.packageName);
9493             }
9494
9495             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9496                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9497             }
9498
9499             if ((scanFlags & SCAN_BOOTING) == 0
9500                     && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9501                 // Check all shared libraries and map to their actual file path.
9502                 // We only do this here for apps not on a system dir, because those
9503                 // are the only ones that can fail an install due to this.  We
9504                 // will take care of the system apps by updating all of their
9505                 // library paths after the scan is done. Also during the initial
9506                 // scan don't update any libs as we do this wholesale after all
9507                 // apps are scanned to avoid dependency based scanning.
9508                 updateSharedLibrariesLPr(pkg, null);
9509             }
9510
9511             if (mFoundPolicyFile) {
9512                 SELinuxMMAC.assignSeInfoValue(pkg);
9513             }
9514             pkg.applicationInfo.uid = pkgSetting.appId;
9515             pkg.mExtras = pkgSetting;
9516
9517
9518             // Static shared libs have same package with different versions where
9519             // we internally use a synthetic package name to allow multiple versions
9520             // of the same package, therefore we need to compare signatures against
9521             // the package setting for the latest library version.
9522             PackageSetting signatureCheckPs = pkgSetting;
9523             if (pkg.applicationInfo.isStaticSharedLibrary()) {
9524                 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9525                 if (libraryEntry != null) {
9526                     signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9527                 }
9528             }
9529
9530             if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9531                 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9532                     // We just determined the app is signed correctly, so bring
9533                     // over the latest parsed certs.
9534                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
9535                 } else {
9536                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9537                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9538                                 "Package " + pkg.packageName + " upgrade keys do not match the "
9539                                 + "previously installed version");
9540                     } else {
9541                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
9542                         String msg = "System package " + pkg.packageName
9543                                 + " signature changed; retaining data.";
9544                         reportSettingsProblem(Log.WARN, msg);
9545                     }
9546                 }
9547             } else {
9548                 try {
9549                     // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9550                     verifySignaturesLP(signatureCheckPs, pkg);
9551                     // We just determined the app is signed correctly, so bring
9552                     // over the latest parsed certs.
9553                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
9554                 } catch (PackageManagerException e) {
9555                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9556                         throw e;
9557                     }
9558                     // The signature has changed, but this package is in the system
9559                     // image...  let's recover!
9560                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
9561                     // However...  if this package is part of a shared user, but it
9562                     // doesn't match the signature of the shared user, let's fail.
9563                     // What this means is that you can't change the signatures
9564                     // associated with an overall shared user, which doesn't seem all
9565                     // that unreasonable.
9566                     if (signatureCheckPs.sharedUser != null) {
9567                         if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9568                                 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9569                             throw new PackageManagerException(
9570                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9571                                     "Signature mismatch for shared user: "
9572                                             + pkgSetting.sharedUser);
9573                         }
9574                     }
9575                     // File a report about this.
9576                     String msg = "System package " + pkg.packageName
9577                             + " signature changed; retaining data.";
9578                     reportSettingsProblem(Log.WARN, msg);
9579                 }
9580             }
9581
9582             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9583                 // This package wants to adopt ownership of permissions from
9584                 // another package.
9585                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9586                     final String origName = pkg.mAdoptPermissions.get(i);
9587                     final PackageSetting orig = mSettings.getPackageLPr(origName);
9588                     if (orig != null) {
9589                         if (verifyPackageUpdateLPr(orig, pkg)) {
9590                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
9591                                     + pkg.packageName);
9592                             // SIDE EFFECTS; updates permissions system state; move elsewhere
9593                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
9594                         }
9595                     }
9596                 }
9597             }
9598         }
9599
9600         pkg.applicationInfo.processName = fixProcessName(
9601                 pkg.applicationInfo.packageName,
9602                 pkg.applicationInfo.processName);
9603
9604         if (pkg != mPlatformPackage) {
9605             // Get all of our default paths setup
9606             pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
9607         }
9608
9609         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
9610
9611         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
9612             if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9613                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
9614                 derivePackageAbi(
9615                         pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
9616                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9617
9618                 // Some system apps still use directory structure for native libraries
9619                 // in which case we might end up not detecting abi solely based on apk
9620                 // structure. Try to detect abi based on directory structure.
9621                 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
9622                         pkg.applicationInfo.primaryCpuAbi == null) {
9623                     setBundledAppAbisAndRoots(pkg, pkgSetting);
9624                     setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9625                 }
9626             } else {
9627                 // This is not a first boot or an upgrade, don't bother deriving the
9628                 // ABI during the scan. Instead, trust the value that was stored in the
9629                 // package setting.
9630                 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
9631                 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
9632
9633                 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9634
9635                 if (DEBUG_ABI_SELECTION) {
9636                     Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
9637                         pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
9638                         pkg.applicationInfo.secondaryCpuAbi);
9639                 }
9640             }
9641         } else {
9642             if ((scanFlags & SCAN_MOVE) != 0) {
9643                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
9644                 // but we already have this packages package info in the PackageSetting. We just
9645                 // use that and derive the native library path based on the new codepath.
9646                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
9647                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
9648             }
9649
9650             // Set native library paths again. For moves, the path will be updated based on the
9651             // ABIs we've determined above. For non-moves, the path will be updated based on the
9652             // ABIs we determined during compilation, but the path will depend on the final
9653             // package path (after the rename away from the stage path).
9654             setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9655         }
9656
9657         // This is a special case for the "system" package, where the ABI is
9658         // dictated by the zygote configuration (and init.rc). We should keep track
9659         // of this ABI so that we can deal with "normal" applications that run under
9660         // the same UID correctly.
9661         if (mPlatformPackage == pkg) {
9662             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
9663                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
9664         }
9665
9666         // If there's a mismatch between the abi-override in the package setting
9667         // and the abiOverride specified for the install. Warn about this because we
9668         // would've already compiled the app without taking the package setting into
9669         // account.
9670         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
9671             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
9672                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
9673                         " for package " + pkg.packageName);
9674             }
9675         }
9676
9677         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9678         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9679         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
9680
9681         // Copy the derived override back to the parsed package, so that we can
9682         // update the package settings accordingly.
9683         pkg.cpuAbiOverride = cpuAbiOverride;
9684
9685         if (DEBUG_ABI_SELECTION) {
9686             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
9687                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
9688                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
9689         }
9690
9691         // Push the derived path down into PackageSettings so we know what to
9692         // clean up at uninstall time.
9693         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
9694
9695         if (DEBUG_ABI_SELECTION) {
9696             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
9697                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
9698                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
9699         }
9700
9701         // SIDE EFFECTS; removes DEX files from disk; move elsewhere
9702         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
9703             // We don't do this here during boot because we can do it all
9704             // at once after scanning all existing packages.
9705             //
9706             // We also do this *before* we perform dexopt on this package, so that
9707             // we can avoid redundant dexopts, and also to make sure we've got the
9708             // code and package path correct.
9709             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
9710         }
9711
9712         if (mFactoryTest && pkg.requestedPermissions.contains(
9713                 android.Manifest.permission.FACTORY_TEST)) {
9714             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
9715         }
9716
9717         if (isSystemApp(pkg)) {
9718             pkgSetting.isOrphaned = true;
9719         }
9720
9721         // Take care of first install / last update times.
9722         final long scanFileTime = getLastModifiedTime(pkg, scanFile);
9723         if (currentTime != 0) {
9724             if (pkgSetting.firstInstallTime == 0) {
9725                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
9726             } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
9727                 pkgSetting.lastUpdateTime = currentTime;
9728             }
9729         } else if (pkgSetting.firstInstallTime == 0) {
9730             // We need *something*.  Take time time stamp of the file.
9731             pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
9732         } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
9733             if (scanFileTime != pkgSetting.timeStamp) {
9734                 // A package on the system image has changed; consider this
9735                 // to be an update.
9736                 pkgSetting.lastUpdateTime = scanFileTime;
9737             }
9738         }
9739         pkgSetting.setTimeStamp(scanFileTime);
9740
9741         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9742             if (nonMutatedPs != null) {
9743                 synchronized (mPackages) {
9744                     mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
9745                 }
9746             }
9747         } else {
9748             final int userId = user == null ? 0 : user.getIdentifier();
9749             // Modify state for the given package setting
9750             commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9751                     (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9752             if (pkgSetting.getInstantApp(userId)) {
9753                 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9754             }
9755         }
9756         return pkg;
9757     }
9758
9759     /**
9760      * Applies policy to the parsed package based upon the given policy flags.
9761      * Ensures the package is in a good state.
9762      * <p>
9763      * Implementation detail: This method must NOT have any side effect. It would
9764      * ideally be static, but, it requires locks to read system state.
9765      */
9766     private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
9767         if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
9768             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
9769             if (pkg.applicationInfo.isDirectBootAware()) {
9770                 // we're direct boot aware; set for all components
9771                 for (PackageParser.Service s : pkg.services) {
9772                     s.info.encryptionAware = s.info.directBootAware = true;
9773                 }
9774                 for (PackageParser.Provider p : pkg.providers) {
9775                     p.info.encryptionAware = p.info.directBootAware = true;
9776                 }
9777                 for (PackageParser.Activity a : pkg.activities) {
9778                     a.info.encryptionAware = a.info.directBootAware = true;
9779                 }
9780                 for (PackageParser.Activity r : pkg.receivers) {
9781                     r.info.encryptionAware = r.info.directBootAware = true;
9782                 }
9783             }
9784         } else {
9785             // Only allow system apps to be flagged as core apps.
9786             pkg.coreApp = false;
9787             // clear flags not applicable to regular apps
9788             pkg.applicationInfo.privateFlags &=
9789                     ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
9790             pkg.applicationInfo.privateFlags &=
9791                     ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
9792         }
9793         pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
9794
9795         if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
9796             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9797         }
9798
9799         if (!isSystemApp(pkg)) {
9800             // Only system apps can use these features.
9801             pkg.mOriginalPackages = null;
9802             pkg.mRealPackage = null;
9803             pkg.mAdoptPermissions = null;
9804         }
9805     }
9806
9807     /**
9808      * Asserts the parsed package is valid according to the given policy. If the
9809      * package is invalid, for whatever reason, throws {@link PackageManagerException}.
9810      * <p>
9811      * Implementation detail: This method must NOT have any side effects. It would
9812      * ideally be static, but, it requires locks to read system state.
9813      *
9814      * @throws PackageManagerException If the package fails any of the validation checks
9815      */
9816     private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
9817             throws PackageManagerException {
9818         if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
9819             assertCodePolicy(pkg);
9820         }
9821
9822         if (pkg.applicationInfo.getCodePath() == null ||
9823                 pkg.applicationInfo.getResourcePath() == null) {
9824             // Bail out. The resource and code paths haven't been set.
9825             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9826                     "Code and resource paths haven't been set correctly");
9827         }
9828
9829         // Make sure we're not adding any bogus keyset info
9830         KeySetManagerService ksms = mSettings.mKeySetManagerService;
9831         ksms.assertScannedPackageValid(pkg);
9832
9833         synchronized (mPackages) {
9834             // The special "android" package can only be defined once
9835             if (pkg.packageName.equals("android")) {
9836                 if (mAndroidApplication != null) {
9837                     Slog.w(TAG, "*************************************************");
9838                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
9839                     Slog.w(TAG, " codePath=" + pkg.codePath);
9840                     Slog.w(TAG, "*************************************************");
9841                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9842                             "Core android package being redefined.  Skipping.");
9843                 }
9844             }
9845
9846             // A package name must be unique; don't allow duplicates
9847             if (mPackages.containsKey(pkg.packageName)) {
9848                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9849                         "Application package " + pkg.packageName
9850                         + " already installed.  Skipping duplicate.");
9851             }
9852
9853             if (pkg.applicationInfo.isStaticSharedLibrary()) {
9854                 // Static libs have a synthetic package name containing the version
9855                 // but we still want the base name to be unique.
9856                 if (mPackages.containsKey(pkg.manifestPackageName)) {
9857                     throw new PackageManagerException(
9858                             "Duplicate static shared lib provider package");
9859                 }
9860
9861                 // Static shared libraries should have at least O target SDK
9862                 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
9863                     throw new PackageManagerException(
9864                             "Packages declaring static-shared libs must target O SDK or higher");
9865                 }
9866
9867                 // Package declaring static a shared lib cannot be instant apps
9868                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
9869                     throw new PackageManagerException(
9870                             "Packages declaring static-shared libs cannot be instant apps");
9871                 }
9872
9873                 // Package declaring static a shared lib cannot be renamed since the package
9874                 // name is synthetic and apps can't code around package manager internals.
9875                 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
9876                     throw new PackageManagerException(
9877                             "Packages declaring static-shared libs cannot be renamed");
9878                 }
9879
9880                 // Package declaring static a shared lib cannot declare child packages
9881                 if (!ArrayUtils.isEmpty(pkg.childPackages)) {
9882                     throw new PackageManagerException(
9883                             "Packages declaring static-shared libs cannot have child packages");
9884                 }
9885
9886                 // Package declaring static a shared lib cannot declare dynamic libs
9887                 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
9888                     throw new PackageManagerException(
9889                             "Packages declaring static-shared libs cannot declare dynamic libs");
9890                 }
9891
9892                 // Package declaring static a shared lib cannot declare shared users
9893                 if (pkg.mSharedUserId != null) {
9894                     throw new PackageManagerException(
9895                             "Packages declaring static-shared libs cannot declare shared users");
9896                 }
9897
9898                 // Static shared libs cannot declare activities
9899                 if (!pkg.activities.isEmpty()) {
9900                     throw new PackageManagerException(
9901                             "Static shared libs cannot declare activities");
9902                 }
9903
9904                 // Static shared libs cannot declare services
9905                 if (!pkg.services.isEmpty()) {
9906                     throw new PackageManagerException(
9907                             "Static shared libs cannot declare services");
9908                 }
9909
9910                 // Static shared libs cannot declare providers
9911                 if (!pkg.providers.isEmpty()) {
9912                     throw new PackageManagerException(
9913                             "Static shared libs cannot declare content providers");
9914                 }
9915
9916                 // Static shared libs cannot declare receivers
9917                 if (!pkg.receivers.isEmpty()) {
9918                     throw new PackageManagerException(
9919                             "Static shared libs cannot declare broadcast receivers");
9920                 }
9921
9922                 // Static shared libs cannot declare permission groups
9923                 if (!pkg.permissionGroups.isEmpty()) {
9924                     throw new PackageManagerException(
9925                             "Static shared libs cannot declare permission groups");
9926                 }
9927
9928                 // Static shared libs cannot declare permissions
9929                 if (!pkg.permissions.isEmpty()) {
9930                     throw new PackageManagerException(
9931                             "Static shared libs cannot declare permissions");
9932                 }
9933
9934                 // Static shared libs cannot declare protected broadcasts
9935                 if (pkg.protectedBroadcasts != null) {
9936                     throw new PackageManagerException(
9937                             "Static shared libs cannot declare protected broadcasts");
9938                 }
9939
9940                 // Static shared libs cannot be overlay targets
9941                 if (pkg.mOverlayTarget != null) {
9942                     throw new PackageManagerException(
9943                             "Static shared libs cannot be overlay targets");
9944                 }
9945
9946                 // The version codes must be ordered as lib versions
9947                 int minVersionCode = Integer.MIN_VALUE;
9948                 int maxVersionCode = Integer.MAX_VALUE;
9949
9950                 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9951                         pkg.staticSharedLibName);
9952                 if (versionedLib != null) {
9953                     final int versionCount = versionedLib.size();
9954                     for (int i = 0; i < versionCount; i++) {
9955                         SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
9956                         // TODO: We will change version code to long, so in the new API it is long
9957                         final int libVersionCode = (int) libInfo.getDeclaringPackage()
9958                                 .getVersionCode();
9959                         if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
9960                             minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
9961                         } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
9962                             maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
9963                         } else {
9964                             minVersionCode = maxVersionCode = libVersionCode;
9965                             break;
9966                         }
9967                     }
9968                 }
9969                 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
9970                     throw new PackageManagerException("Static shared"
9971                             + " lib version codes must be ordered as lib versions");
9972                 }
9973             }
9974
9975             // Only privileged apps and updated privileged apps can add child packages.
9976             if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
9977                 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
9978                     throw new PackageManagerException("Only privileged apps can add child "
9979                             + "packages. Ignoring package " + pkg.packageName);
9980                 }
9981                 final int childCount = pkg.childPackages.size();
9982                 for (int i = 0; i < childCount; i++) {
9983                     PackageParser.Package childPkg = pkg.childPackages.get(i);
9984                     if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
9985                             childPkg.packageName)) {
9986                         throw new PackageManagerException("Can't override child of "
9987                                 + "another disabled app. Ignoring package " + pkg.packageName);
9988                     }
9989                 }
9990             }
9991
9992             // If we're only installing presumed-existing packages, require that the
9993             // scanned APK is both already known and at the path previously established
9994             // for it.  Previously unknown packages we pick up normally, but if we have an
9995             // a priori expectation about this package's install presence, enforce it.
9996             // With a singular exception for new system packages. When an OTA contains
9997             // a new system package, we allow the codepath to change from a system location
9998             // to the user-installed location. If we don't allow this change, any newer,
9999             // user-installed version of the application will be ignored.
10000             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10001                 if (mExpectingBetter.containsKey(pkg.packageName)) {
10002                     logCriticalInfo(Log.WARN,
10003                             "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10004                 } else {
10005                     PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10006                     if (known != null) {
10007                         if (DEBUG_PACKAGE_SCANNING) {
10008                             Log.d(TAG, "Examining " + pkg.codePath
10009                                     + " and requiring known paths " + known.codePathString
10010                                     + " & " + known.resourcePathString);
10011                         }
10012                         if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10013                                 || !pkg.applicationInfo.getResourcePath().equals(
10014                                         known.resourcePathString)) {
10015                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10016                                     "Application package " + pkg.packageName
10017                                     + " found at " + pkg.applicationInfo.getCodePath()
10018                                     + " but expected at " + known.codePathString
10019                                     + "; ignoring.");
10020                         }
10021                     }
10022                 }
10023             }
10024
10025             // Verify that this new package doesn't have any content providers
10026             // that conflict with existing packages.  Only do this if the
10027             // package isn't already installed, since we don't want to break
10028             // things that are installed.
10029             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10030                 final int N = pkg.providers.size();
10031                 int i;
10032                 for (i=0; i<N; i++) {
10033                     PackageParser.Provider p = pkg.providers.get(i);
10034                     if (p.info.authority != null) {
10035                         String names[] = p.info.authority.split(";");
10036                         for (int j = 0; j < names.length; j++) {
10037                             if (mProvidersByAuthority.containsKey(names[j])) {
10038                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10039                                 final String otherPackageName =
10040                                         ((other != null && other.getComponentName() != null) ?
10041                                                 other.getComponentName().getPackageName() : "?");
10042                                 throw new PackageManagerException(
10043                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
10044                                         "Can't install because provider name " + names[j]
10045                                                 + " (in package " + pkg.applicationInfo.packageName
10046                                                 + ") is already used by " + otherPackageName);
10047                             }
10048                         }
10049                     }
10050                 }
10051             }
10052         }
10053     }
10054
10055     private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10056             int type, String declaringPackageName, int declaringVersionCode) {
10057         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10058         if (versionedLib == null) {
10059             versionedLib = new SparseArray<>();
10060             mSharedLibraries.put(name, versionedLib);
10061             if (type == SharedLibraryInfo.TYPE_STATIC) {
10062                 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10063             }
10064         } else if (versionedLib.indexOfKey(version) >= 0) {
10065             return false;
10066         }
10067         SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10068                 version, type, declaringPackageName, declaringVersionCode);
10069         versionedLib.put(version, libEntry);
10070         return true;
10071     }
10072
10073     private boolean removeSharedLibraryLPw(String name, int version) {
10074         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10075         if (versionedLib == null) {
10076             return false;
10077         }
10078         final int libIdx = versionedLib.indexOfKey(version);
10079         if (libIdx < 0) {
10080             return false;
10081         }
10082         SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10083         versionedLib.remove(version);
10084         if (versionedLib.size() <= 0) {
10085             mSharedLibraries.remove(name);
10086             if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10087                 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10088                         .getPackageName());
10089             }
10090         }
10091         return true;
10092     }
10093
10094     /**
10095      * Adds a scanned package to the system. When this method is finished, the package will
10096      * be available for query, resolution, etc...
10097      */
10098     private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10099             UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10100         final String pkgName = pkg.packageName;
10101         if (mCustomResolverComponentName != null &&
10102                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10103             setUpCustomResolverActivity(pkg);
10104         }
10105
10106         if (pkg.packageName.equals("android")) {
10107             synchronized (mPackages) {
10108                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10109                     // Set up information for our fall-back user intent resolution activity.
10110                     mPlatformPackage = pkg;
10111                     pkg.mVersionCode = mSdkVersion;
10112                     mAndroidApplication = pkg.applicationInfo;
10113                     if (!mResolverReplaced) {
10114                         mResolveActivity.applicationInfo = mAndroidApplication;
10115                         mResolveActivity.name = ResolverActivity.class.getName();
10116                         mResolveActivity.packageName = mAndroidApplication.packageName;
10117                         mResolveActivity.processName = "system:ui";
10118                         mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10119                         mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10120                         mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10121                         mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10122                         mResolveActivity.exported = true;
10123                         mResolveActivity.enabled = true;
10124                         mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10125                         mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10126                                 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10127                                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
10128                                 | ActivityInfo.CONFIG_ORIENTATION
10129                                 | ActivityInfo.CONFIG_KEYBOARD
10130                                 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10131                         mResolveInfo.activityInfo = mResolveActivity;
10132                         mResolveInfo.priority = 0;
10133                         mResolveInfo.preferredOrder = 0;
10134                         mResolveInfo.match = 0;
10135                         mResolveComponentName = new ComponentName(
10136                                 mAndroidApplication.packageName, mResolveActivity.name);
10137                     }
10138                 }
10139             }
10140         }
10141
10142         ArrayList<PackageParser.Package> clientLibPkgs = null;
10143         // writer
10144         synchronized (mPackages) {
10145             boolean hasStaticSharedLibs = false;
10146
10147             // Any app can add new static shared libraries
10148             if (pkg.staticSharedLibName != null) {
10149                 // Static shared libs don't allow renaming as they have synthetic package
10150                 // names to allow install of multiple versions, so use name from manifest.
10151                 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10152                         pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10153                         pkg.manifestPackageName, pkg.mVersionCode)) {
10154                     hasStaticSharedLibs = true;
10155                 } else {
10156                     Slog.w(TAG, "Package " + pkg.packageName + " library "
10157                                 + pkg.staticSharedLibName + " already exists; skipping");
10158                 }
10159                 // Static shared libs cannot be updated once installed since they
10160                 // use synthetic package name which includes the version code, so
10161                 // not need to update other packages's shared lib dependencies.
10162             }
10163
10164             if (!hasStaticSharedLibs
10165                     && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10166                 // Only system apps can add new dynamic shared libraries.
10167                 if (pkg.libraryNames != null) {
10168                     for (int i = 0; i < pkg.libraryNames.size(); i++) {
10169                         String name = pkg.libraryNames.get(i);
10170                         boolean allowed = false;
10171                         if (pkg.isUpdatedSystemApp()) {
10172                             // New library entries can only be added through the
10173                             // system image.  This is important to get rid of a lot
10174                             // of nasty edge cases: for example if we allowed a non-
10175                             // system update of the app to add a library, then uninstalling
10176                             // the update would make the library go away, and assumptions
10177                             // we made such as through app install filtering would now
10178                             // have allowed apps on the device which aren't compatible
10179                             // with it.  Better to just have the restriction here, be
10180                             // conservative, and create many fewer cases that can negatively
10181                             // impact the user experience.
10182                             final PackageSetting sysPs = mSettings
10183                                     .getDisabledSystemPkgLPr(pkg.packageName);
10184                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10185                                 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10186                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10187                                         allowed = true;
10188                                         break;
10189                                     }
10190                                 }
10191                             }
10192                         } else {
10193                             allowed = true;
10194                         }
10195                         if (allowed) {
10196                             if (!addSharedLibraryLPw(null, pkg.packageName, name,
10197                                     SharedLibraryInfo.VERSION_UNDEFINED,
10198                                     SharedLibraryInfo.TYPE_DYNAMIC,
10199                                     pkg.packageName, pkg.mVersionCode)) {
10200                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
10201                                         + name + " already exists; skipping");
10202                             }
10203                         } else {
10204                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10205                                     + name + " that is not declared on system image; skipping");
10206                         }
10207                     }
10208
10209                     if ((scanFlags & SCAN_BOOTING) == 0) {
10210                         // If we are not booting, we need to update any applications
10211                         // that are clients of our shared library.  If we are booting,
10212                         // this will all be done once the scan is complete.
10213                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10214                     }
10215                 }
10216             }
10217         }
10218
10219         if ((scanFlags & SCAN_BOOTING) != 0) {
10220             // No apps can run during boot scan, so they don't need to be frozen
10221         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10222             // Caller asked to not kill app, so it's probably not frozen
10223         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10224             // Caller asked us to ignore frozen check for some reason; they
10225             // probably didn't know the package name
10226         } else {
10227             // We're doing major surgery on this package, so it better be frozen
10228             // right now to keep it from launching
10229             checkPackageFrozen(pkgName);
10230         }
10231
10232         // Also need to kill any apps that are dependent on the library.
10233         if (clientLibPkgs != null) {
10234             for (int i=0; i<clientLibPkgs.size(); i++) {
10235                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
10236                 killApplication(clientPkg.applicationInfo.packageName,
10237                         clientPkg.applicationInfo.uid, "update lib");
10238             }
10239         }
10240
10241         // writer
10242         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10243
10244         synchronized (mPackages) {
10245             // We don't expect installation to fail beyond this point
10246
10247             // Add the new setting to mSettings
10248             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10249             // Add the new setting to mPackages
10250             mPackages.put(pkg.applicationInfo.packageName, pkg);
10251             // Make sure we don't accidentally delete its data.
10252             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10253             while (iter.hasNext()) {
10254                 PackageCleanItem item = iter.next();
10255                 if (pkgName.equals(item.packageName)) {
10256                     iter.remove();
10257                 }
10258             }
10259
10260             // Add the package's KeySets to the global KeySetManagerService
10261             KeySetManagerService ksms = mSettings.mKeySetManagerService;
10262             ksms.addScannedPackageLPw(pkg);
10263
10264             int N = pkg.providers.size();
10265             StringBuilder r = null;
10266             int i;
10267             for (i=0; i<N; i++) {
10268                 PackageParser.Provider p = pkg.providers.get(i);
10269                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10270                         p.info.processName);
10271                 mProviders.addProvider(p);
10272                 p.syncable = p.info.isSyncable;
10273                 if (p.info.authority != null) {
10274                     String names[] = p.info.authority.split(";");
10275                     p.info.authority = null;
10276                     for (int j = 0; j < names.length; j++) {
10277                         if (j == 1 && p.syncable) {
10278                             // We only want the first authority for a provider to possibly be
10279                             // syncable, so if we already added this provider using a different
10280                             // authority clear the syncable flag. We copy the provider before
10281                             // changing it because the mProviders object contains a reference
10282                             // to a provider that we don't want to change.
10283                             // Only do this for the second authority since the resulting provider
10284                             // object can be the same for all future authorities for this provider.
10285                             p = new PackageParser.Provider(p);
10286                             p.syncable = false;
10287                         }
10288                         if (!mProvidersByAuthority.containsKey(names[j])) {
10289                             mProvidersByAuthority.put(names[j], p);
10290                             if (p.info.authority == null) {
10291                                 p.info.authority = names[j];
10292                             } else {
10293                                 p.info.authority = p.info.authority + ";" + names[j];
10294                             }
10295                             if (DEBUG_PACKAGE_SCANNING) {
10296                                 if (chatty)
10297                                     Log.d(TAG, "Registered content provider: " + names[j]
10298                                             + ", className = " + p.info.name + ", isSyncable = "
10299                                             + p.info.isSyncable);
10300                             }
10301                         } else {
10302                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10303                             Slog.w(TAG, "Skipping provider name " + names[j] +
10304                                     " (in package " + pkg.applicationInfo.packageName +
10305                                     "): name already used by "
10306                                     + ((other != null && other.getComponentName() != null)
10307                                             ? other.getComponentName().getPackageName() : "?"));
10308                         }
10309                     }
10310                 }
10311                 if (chatty) {
10312                     if (r == null) {
10313                         r = new StringBuilder(256);
10314                     } else {
10315                         r.append(' ');
10316                     }
10317                     r.append(p.info.name);
10318                 }
10319             }
10320             if (r != null) {
10321                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10322             }
10323
10324             N = pkg.services.size();
10325             r = null;
10326             for (i=0; i<N; i++) {
10327                 PackageParser.Service s = pkg.services.get(i);
10328                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10329                         s.info.processName);
10330                 mServices.addService(s);
10331                 if (chatty) {
10332                     if (r == null) {
10333                         r = new StringBuilder(256);
10334                     } else {
10335                         r.append(' ');
10336                     }
10337                     r.append(s.info.name);
10338                 }
10339             }
10340             if (r != null) {
10341                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10342             }
10343
10344             N = pkg.receivers.size();
10345             r = null;
10346             for (i=0; i<N; i++) {
10347                 PackageParser.Activity a = pkg.receivers.get(i);
10348                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10349                         a.info.processName);
10350                 mReceivers.addActivity(a, "receiver");
10351                 if (chatty) {
10352                     if (r == null) {
10353                         r = new StringBuilder(256);
10354                     } else {
10355                         r.append(' ');
10356                     }
10357                     r.append(a.info.name);
10358                 }
10359             }
10360             if (r != null) {
10361                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10362             }
10363
10364             N = pkg.activities.size();
10365             r = null;
10366             for (i=0; i<N; i++) {
10367                 PackageParser.Activity a = pkg.activities.get(i);
10368                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10369                         a.info.processName);
10370                 mActivities.addActivity(a, "activity");
10371                 if (chatty) {
10372                     if (r == null) {
10373                         r = new StringBuilder(256);
10374                     } else {
10375                         r.append(' ');
10376                     }
10377                     r.append(a.info.name);
10378                 }
10379             }
10380             if (r != null) {
10381                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10382             }
10383
10384             N = pkg.permissionGroups.size();
10385             r = null;
10386             for (i=0; i<N; i++) {
10387                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10388                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10389                 final String curPackageName = cur == null ? null : cur.info.packageName;
10390                 // Dont allow ephemeral apps to define new permission groups.
10391                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10392                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10393                             + pg.info.packageName
10394                             + " ignored: instant apps cannot define new permission groups.");
10395                     continue;
10396                 }
10397                 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10398                 if (cur == null || isPackageUpdate) {
10399                     mPermissionGroups.put(pg.info.name, pg);
10400                     if (chatty) {
10401                         if (r == null) {
10402                             r = new StringBuilder(256);
10403                         } else {
10404                             r.append(' ');
10405                         }
10406                         if (isPackageUpdate) {
10407                             r.append("UPD:");
10408                         }
10409                         r.append(pg.info.name);
10410                     }
10411                 } else {
10412                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10413                             + pg.info.packageName + " ignored: original from "
10414                             + cur.info.packageName);
10415                     if (chatty) {
10416                         if (r == null) {
10417                             r = new StringBuilder(256);
10418                         } else {
10419                             r.append(' ');
10420                         }
10421                         r.append("DUP:");
10422                         r.append(pg.info.name);
10423                     }
10424                 }
10425             }
10426             if (r != null) {
10427                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
10428             }
10429
10430             N = pkg.permissions.size();
10431             r = null;
10432             for (i=0; i<N; i++) {
10433                 PackageParser.Permission p = pkg.permissions.get(i);
10434
10435                 // Dont allow ephemeral apps to define new permissions.
10436                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10437                     Slog.w(TAG, "Permission " + p.info.name + " from package "
10438                             + p.info.packageName
10439                             + " ignored: instant apps cannot define new permissions.");
10440                     continue;
10441                 }
10442
10443                 // Assume by default that we did not install this permission into the system.
10444                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10445
10446                 // Now that permission groups have a special meaning, we ignore permission
10447                 // groups for legacy apps to prevent unexpected behavior. In particular,
10448                 // permissions for one app being granted to someone just becase they happen
10449                 // to be in a group defined by another app (before this had no implications).
10450                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10451                     p.group = mPermissionGroups.get(p.info.group);
10452                     // Warn for a permission in an unknown group.
10453                     if (p.info.group != null && p.group == null) {
10454                         Slog.w(TAG, "Permission " + p.info.name + " from package "
10455                                 + p.info.packageName + " in an unknown group " + p.info.group);
10456                     }
10457                 }
10458
10459                 ArrayMap<String, BasePermission> permissionMap =
10460                         p.tree ? mSettings.mPermissionTrees
10461                                 : mSettings.mPermissions;
10462                 BasePermission bp = permissionMap.get(p.info.name);
10463
10464                 // Allow system apps to redefine non-system permissions
10465                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10466                     final boolean currentOwnerIsSystem = (bp.perm != null
10467                             && isSystemApp(bp.perm.owner));
10468                     if (isSystemApp(p.owner)) {
10469                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10470                             // It's a built-in permission and no owner, take ownership now
10471                             bp.packageSetting = pkgSetting;
10472                             bp.perm = p;
10473                             bp.uid = pkg.applicationInfo.uid;
10474                             bp.sourcePackage = p.info.packageName;
10475                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10476                         } else if (!currentOwnerIsSystem) {
10477                             String msg = "New decl " + p.owner + " of permission  "
10478                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
10479                             reportSettingsProblem(Log.WARN, msg);
10480                             bp = null;
10481                         }
10482                     }
10483                 }
10484
10485                 if (bp == null) {
10486                     bp = new BasePermission(p.info.name, p.info.packageName,
10487                             BasePermission.TYPE_NORMAL);
10488                     permissionMap.put(p.info.name, bp);
10489                 }
10490
10491                 if (bp.perm == null) {
10492                     if (bp.sourcePackage == null
10493                             || bp.sourcePackage.equals(p.info.packageName)) {
10494                         BasePermission tree = findPermissionTreeLP(p.info.name);
10495                         if (tree == null
10496                                 || tree.sourcePackage.equals(p.info.packageName)) {
10497                             bp.packageSetting = pkgSetting;
10498                             bp.perm = p;
10499                             bp.uid = pkg.applicationInfo.uid;
10500                             bp.sourcePackage = p.info.packageName;
10501                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10502                             if (chatty) {
10503                                 if (r == null) {
10504                                     r = new StringBuilder(256);
10505                                 } else {
10506                                     r.append(' ');
10507                                 }
10508                                 r.append(p.info.name);
10509                             }
10510                         } else {
10511                             Slog.w(TAG, "Permission " + p.info.name + " from package "
10512                                     + p.info.packageName + " ignored: base tree "
10513                                     + tree.name + " is from package "
10514                                     + tree.sourcePackage);
10515                         }
10516                     } else {
10517                         Slog.w(TAG, "Permission " + p.info.name + " from package "
10518                                 + p.info.packageName + " ignored: original from "
10519                                 + bp.sourcePackage);
10520                     }
10521                 } else if (chatty) {
10522                     if (r == null) {
10523                         r = new StringBuilder(256);
10524                     } else {
10525                         r.append(' ');
10526                     }
10527                     r.append("DUP:");
10528                     r.append(p.info.name);
10529                 }
10530                 if (bp.perm == p) {
10531                     bp.protectionLevel = p.info.protectionLevel;
10532                 }
10533             }
10534
10535             if (r != null) {
10536                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
10537             }
10538
10539             N = pkg.instrumentation.size();
10540             r = null;
10541             for (i=0; i<N; i++) {
10542                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10543                 a.info.packageName = pkg.applicationInfo.packageName;
10544                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
10545                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10546                 a.info.splitNames = pkg.splitNames;
10547                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10548                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10549                 a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10550                 a.info.dataDir = pkg.applicationInfo.dataDir;
10551                 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10552                 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10553                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10554                 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10555                 mInstrumentation.put(a.getComponentName(), a);
10556                 if (chatty) {
10557                     if (r == null) {
10558                         r = new StringBuilder(256);
10559                     } else {
10560                         r.append(' ');
10561                     }
10562                     r.append(a.info.name);
10563                 }
10564             }
10565             if (r != null) {
10566                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
10567             }
10568
10569             if (pkg.protectedBroadcasts != null) {
10570                 N = pkg.protectedBroadcasts.size();
10571                 for (i=0; i<N; i++) {
10572                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10573                 }
10574             }
10575         }
10576
10577         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10578     }
10579
10580     /**
10581      * Derive the ABI of a non-system package located at {@code scanFile}. This information
10582      * is derived purely on the basis of the contents of {@code scanFile} and
10583      * {@code cpuAbiOverride}.
10584      *
10585      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10586      */
10587     private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10588                                  String cpuAbiOverride, boolean extractLibs,
10589                                  File appLib32InstallDir)
10590             throws PackageManagerException {
10591         // Give ourselves some initial paths; we'll come back for another
10592         // pass once we've determined ABI below.
10593         setNativeLibraryPaths(pkg, appLib32InstallDir);
10594
10595         // We would never need to extract libs for forward-locked and external packages,
10596         // since the container service will do it for us. We shouldn't attempt to
10597         // extract libs from system app when it was not updated.
10598         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10599                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10600             extractLibs = false;
10601         }
10602
10603         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10604         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10605
10606         NativeLibraryHelper.Handle handle = null;
10607         try {
10608             handle = NativeLibraryHelper.Handle.create(pkg);
10609             // TODO(multiArch): This can be null for apps that didn't go through the
10610             // usual installation process. We can calculate it again, like we
10611             // do during install time.
10612             //
10613             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10614             // unnecessary.
10615             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10616
10617             // Null out the abis so that they can be recalculated.
10618             pkg.applicationInfo.primaryCpuAbi = null;
10619             pkg.applicationInfo.secondaryCpuAbi = null;
10620             if (isMultiArch(pkg.applicationInfo)) {
10621                 // Warn if we've set an abiOverride for multi-lib packages..
10622                 // By definition, we need to copy both 32 and 64 bit libraries for
10623                 // such packages.
10624                 if (pkg.cpuAbiOverride != null
10625                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10626                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10627                 }
10628
10629                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10630                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10631                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10632                     if (extractLibs) {
10633                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10634                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10635                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10636                                 useIsaSpecificSubdirs);
10637                     } else {
10638                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10639                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10640                     }
10641                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10642                 }
10643
10644                 maybeThrowExceptionForMultiArchCopy(
10645                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10646
10647                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10648                     if (extractLibs) {
10649                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10650                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10651                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10652                                 useIsaSpecificSubdirs);
10653                     } else {
10654                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10655                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10656                     }
10657                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10658                 }
10659
10660                 maybeThrowExceptionForMultiArchCopy(
10661                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
10662
10663                 if (abi64 >= 0) {
10664                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
10665                 }
10666
10667                 if (abi32 >= 0) {
10668                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
10669                     if (abi64 >= 0) {
10670                         if (pkg.use32bitAbi) {
10671                             pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
10672                             pkg.applicationInfo.primaryCpuAbi = abi;
10673                         } else {
10674                             pkg.applicationInfo.secondaryCpuAbi = abi;
10675                         }
10676                     } else {
10677                         pkg.applicationInfo.primaryCpuAbi = abi;
10678                     }
10679                 }
10680
10681             } else {
10682                 String[] abiList = (cpuAbiOverride != null) ?
10683                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
10684
10685                 // Enable gross and lame hacks for apps that are built with old
10686                 // SDK tools. We must scan their APKs for renderscript bitcode and
10687                 // not launch them if it's present. Don't bother checking on devices
10688                 // that don't have 64 bit support.
10689                 boolean needsRenderScriptOverride = false;
10690                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
10691                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
10692                     abiList = Build.SUPPORTED_32_BIT_ABIS;
10693                     needsRenderScriptOverride = true;
10694                 }
10695
10696                 final int copyRet;
10697                 if (extractLibs) {
10698                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10699                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10700                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
10701                 } else {
10702                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10703                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
10704                 }
10705                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10706
10707                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
10708                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10709                             "Error unpackaging native libs for app, errorCode=" + copyRet);
10710                 }
10711
10712                 if (copyRet >= 0) {
10713                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
10714                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
10715                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
10716                 } else if (needsRenderScriptOverride) {
10717                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
10718                 }
10719             }
10720         } catch (IOException ioe) {
10721             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
10722         } finally {
10723             IoUtils.closeQuietly(handle);
10724         }
10725
10726         // Now that we've calculated the ABIs and determined if it's an internal app,
10727         // we will go ahead and populate the nativeLibraryPath.
10728         setNativeLibraryPaths(pkg, appLib32InstallDir);
10729     }
10730
10731     /**
10732      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
10733      * i.e, so that all packages can be run inside a single process if required.
10734      *
10735      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
10736      * this function will either try and make the ABI for all packages in {@code packagesForUser}
10737      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
10738      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
10739      * updating a package that belongs to a shared user.
10740      *
10741      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
10742      * adds unnecessary complexity.
10743      */
10744     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
10745             PackageParser.Package scannedPackage) {
10746         String requiredInstructionSet = null;
10747         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
10748             requiredInstructionSet = VMRuntime.getInstructionSet(
10749                      scannedPackage.applicationInfo.primaryCpuAbi);
10750         }
10751
10752         PackageSetting requirer = null;
10753         for (PackageSetting ps : packagesForUser) {
10754             // If packagesForUser contains scannedPackage, we skip it. This will happen
10755             // when scannedPackage is an update of an existing package. Without this check,
10756             // we will never be able to change the ABI of any package belonging to a shared
10757             // user, even if it's compatible with other packages.
10758             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10759                 if (ps.primaryCpuAbiString == null) {
10760                     continue;
10761                 }
10762
10763                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
10764                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
10765                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
10766                     // this but there's not much we can do.
10767                     String errorMessage = "Instruction set mismatch, "
10768                             + ((requirer == null) ? "[caller]" : requirer)
10769                             + " requires " + requiredInstructionSet + " whereas " + ps
10770                             + " requires " + instructionSet;
10771                     Slog.w(TAG, errorMessage);
10772                 }
10773
10774                 if (requiredInstructionSet == null) {
10775                     requiredInstructionSet = instructionSet;
10776                     requirer = ps;
10777                 }
10778             }
10779         }
10780
10781         if (requiredInstructionSet != null) {
10782             String adjustedAbi;
10783             if (requirer != null) {
10784                 // requirer != null implies that either scannedPackage was null or that scannedPackage
10785                 // did not require an ABI, in which case we have to adjust scannedPackage to match
10786                 // the ABI of the set (which is the same as requirer's ABI)
10787                 adjustedAbi = requirer.primaryCpuAbiString;
10788                 if (scannedPackage != null) {
10789                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
10790                 }
10791             } else {
10792                 // requirer == null implies that we're updating all ABIs in the set to
10793                 // match scannedPackage.
10794                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
10795             }
10796
10797             for (PackageSetting ps : packagesForUser) {
10798                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10799                     if (ps.primaryCpuAbiString != null) {
10800                         continue;
10801                     }
10802
10803                     ps.primaryCpuAbiString = adjustedAbi;
10804                     if (ps.pkg != null && ps.pkg.applicationInfo != null &&
10805                             !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
10806                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
10807                         Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10808                                 + " (requirer="
10809                                 + (requirer != null ? requirer.pkg : "null")
10810                                 + ", scannedPackage="
10811                                 + (scannedPackage != null ? scannedPackage : "null")
10812                                 + ")");
10813                         try {
10814                             mInstaller.rmdex(ps.codePathString,
10815                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
10816                         } catch (InstallerException ignored) {
10817                         }
10818                     }
10819                 }
10820             }
10821         }
10822     }
10823
10824     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
10825         synchronized (mPackages) {
10826             mResolverReplaced = true;
10827             // Set up information for custom user intent resolution activity.
10828             mResolveActivity.applicationInfo = pkg.applicationInfo;
10829             mResolveActivity.name = mCustomResolverComponentName.getClassName();
10830             mResolveActivity.packageName = pkg.applicationInfo.packageName;
10831             mResolveActivity.processName = pkg.applicationInfo.packageName;
10832             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10833             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
10834                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10835             mResolveActivity.theme = 0;
10836             mResolveActivity.exported = true;
10837             mResolveActivity.enabled = true;
10838             mResolveInfo.activityInfo = mResolveActivity;
10839             mResolveInfo.priority = 0;
10840             mResolveInfo.preferredOrder = 0;
10841             mResolveInfo.match = 0;
10842             mResolveComponentName = mCustomResolverComponentName;
10843             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
10844                     mResolveComponentName);
10845         }
10846     }
10847
10848     private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
10849         if (installerActivity == null) {
10850             if (DEBUG_EPHEMERAL) {
10851                 Slog.d(TAG, "Clear ephemeral installer activity");
10852             }
10853             mInstantAppInstallerActivity = null;
10854             return;
10855         }
10856
10857         if (DEBUG_EPHEMERAL) {
10858             Slog.d(TAG, "Set ephemeral installer activity: "
10859                     + installerActivity.getComponentName());
10860         }
10861         // Set up information for ephemeral installer activity
10862         mInstantAppInstallerActivity = installerActivity;
10863         mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
10864                 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10865         mInstantAppInstallerActivity.exported = true;
10866         mInstantAppInstallerActivity.enabled = true;
10867         mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
10868         mInstantAppInstallerInfo.priority = 0;
10869         mInstantAppInstallerInfo.preferredOrder = 1;
10870         mInstantAppInstallerInfo.isDefault = true;
10871         mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
10872                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
10873     }
10874
10875     private static String calculateBundledApkRoot(final String codePathString) {
10876         final File codePath = new File(codePathString);
10877         final File codeRoot;
10878         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
10879             codeRoot = Environment.getRootDirectory();
10880         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
10881             codeRoot = Environment.getOemDirectory();
10882         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
10883             codeRoot = Environment.getVendorDirectory();
10884         } else {
10885             // Unrecognized code path; take its top real segment as the apk root:
10886             // e.g. /something/app/blah.apk => /something
10887             try {
10888                 File f = codePath.getCanonicalFile();
10889                 File parent = f.getParentFile();    // non-null because codePath is a file
10890                 File tmp;
10891                 while ((tmp = parent.getParentFile()) != null) {
10892                     f = parent;
10893                     parent = tmp;
10894                 }
10895                 codeRoot = f;
10896                 Slog.w(TAG, "Unrecognized code path "
10897                         + codePath + " - using " + codeRoot);
10898             } catch (IOException e) {
10899                 // Can't canonicalize the code path -- shenanigans?
10900                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
10901                 return Environment.getRootDirectory().getPath();
10902             }
10903         }
10904         return codeRoot.getPath();
10905     }
10906
10907     /**
10908      * Derive and set the location of native libraries for the given package,
10909      * which varies depending on where and how the package was installed.
10910      */
10911     private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
10912         final ApplicationInfo info = pkg.applicationInfo;
10913         final String codePath = pkg.codePath;
10914         final File codeFile = new File(codePath);
10915         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
10916         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
10917
10918         info.nativeLibraryRootDir = null;
10919         info.nativeLibraryRootRequiresIsa = false;
10920         info.nativeLibraryDir = null;
10921         info.secondaryNativeLibraryDir = null;
10922
10923         if (isApkFile(codeFile)) {
10924             // Monolithic install
10925             if (bundledApp) {
10926                 // If "/system/lib64/apkname" exists, assume that is the per-package
10927                 // native library directory to use; otherwise use "/system/lib/apkname".
10928                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
10929                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
10930                         getPrimaryInstructionSet(info));
10931
10932                 // This is a bundled system app so choose the path based on the ABI.
10933                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
10934                 // is just the default path.
10935                 final String apkName = deriveCodePathName(codePath);
10936                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
10937                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
10938                         apkName).getAbsolutePath();
10939
10940                 if (info.secondaryCpuAbi != null) {
10941                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
10942                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
10943                             secondaryLibDir, apkName).getAbsolutePath();
10944                 }
10945             } else if (asecApp) {
10946                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
10947                         .getAbsolutePath();
10948             } else {
10949                 final String apkName = deriveCodePathName(codePath);
10950                 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
10951                         .getAbsolutePath();
10952             }
10953
10954             info.nativeLibraryRootRequiresIsa = false;
10955             info.nativeLibraryDir = info.nativeLibraryRootDir;
10956         } else {
10957             // Cluster install
10958             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
10959             info.nativeLibraryRootRequiresIsa = true;
10960
10961             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
10962                     getPrimaryInstructionSet(info)).getAbsolutePath();
10963
10964             if (info.secondaryCpuAbi != null) {
10965                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
10966                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
10967             }
10968         }
10969     }
10970
10971     /**
10972      * Calculate the abis and roots for a bundled app. These can uniquely
10973      * be determined from the contents of the system partition, i.e whether
10974      * it contains 64 or 32 bit shared libraries etc. We do not validate any
10975      * of this information, and instead assume that the system was built
10976      * sensibly.
10977      */
10978     private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
10979                                            PackageSetting pkgSetting) {
10980         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
10981
10982         // If "/system/lib64/apkname" exists, assume that is the per-package
10983         // native library directory to use; otherwise use "/system/lib/apkname".
10984         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
10985         setBundledAppAbi(pkg, apkRoot, apkName);
10986         // pkgSetting might be null during rescan following uninstall of updates
10987         // to a bundled app, so accommodate that possibility.  The settings in
10988         // that case will be established later from the parsed package.
10989         //
10990         // If the settings aren't null, sync them up with what we've just derived.
10991         // note that apkRoot isn't stored in the package settings.
10992         if (pkgSetting != null) {
10993             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10994             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10995         }
10996     }
10997
10998     /**
10999      * Deduces the ABI of a bundled app and sets the relevant fields on the
11000      * parsed pkg object.
11001      *
11002      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11003      *        under which system libraries are installed.
11004      * @param apkName the name of the installed package.
11005      */
11006     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11007         final File codeFile = new File(pkg.codePath);
11008
11009         final boolean has64BitLibs;
11010         final boolean has32BitLibs;
11011         if (isApkFile(codeFile)) {
11012             // Monolithic install
11013             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11014             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11015         } else {
11016             // Cluster install
11017             final File rootDir = new File(codeFile, LIB_DIR_NAME);
11018             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11019                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11020                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11021                 has64BitLibs = (new File(rootDir, isa)).exists();
11022             } else {
11023                 has64BitLibs = false;
11024             }
11025             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11026                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11027                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11028                 has32BitLibs = (new File(rootDir, isa)).exists();
11029             } else {
11030                 has32BitLibs = false;
11031             }
11032         }
11033
11034         if (has64BitLibs && !has32BitLibs) {
11035             // The package has 64 bit libs, but not 32 bit libs. Its primary
11036             // ABI should be 64 bit. We can safely assume here that the bundled
11037             // native libraries correspond to the most preferred ABI in the list.
11038
11039             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11040             pkg.applicationInfo.secondaryCpuAbi = null;
11041         } else if (has32BitLibs && !has64BitLibs) {
11042             // The package has 32 bit libs but not 64 bit libs. Its primary
11043             // ABI should be 32 bit.
11044
11045             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11046             pkg.applicationInfo.secondaryCpuAbi = null;
11047         } else if (has32BitLibs && has64BitLibs) {
11048             // The application has both 64 and 32 bit bundled libraries. We check
11049             // here that the app declares multiArch support, and warn if it doesn't.
11050             //
11051             // We will be lenient here and record both ABIs. The primary will be the
11052             // ABI that's higher on the list, i.e, a device that's configured to prefer
11053             // 64 bit apps will see a 64 bit primary ABI,
11054
11055             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11056                 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11057             }
11058
11059             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11060                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11061                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11062             } else {
11063                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11064                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11065             }
11066         } else {
11067             pkg.applicationInfo.primaryCpuAbi = null;
11068             pkg.applicationInfo.secondaryCpuAbi = null;
11069         }
11070     }
11071
11072     private void killApplication(String pkgName, int appId, String reason) {
11073         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11074     }
11075
11076     private void killApplication(String pkgName, int appId, int userId, String reason) {
11077         // Request the ActivityManager to kill the process(only for existing packages)
11078         // so that we do not end up in a confused state while the user is still using the older
11079         // version of the application while the new one gets installed.
11080         final long token = Binder.clearCallingIdentity();
11081         try {
11082             IActivityManager am = ActivityManager.getService();
11083             if (am != null) {
11084                 try {
11085                     am.killApplication(pkgName, appId, userId, reason);
11086                 } catch (RemoteException e) {
11087                 }
11088             }
11089         } finally {
11090             Binder.restoreCallingIdentity(token);
11091         }
11092     }
11093
11094     private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11095         // Remove the parent package setting
11096         PackageSetting ps = (PackageSetting) pkg.mExtras;
11097         if (ps != null) {
11098             removePackageLI(ps, chatty);
11099         }
11100         // Remove the child package setting
11101         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11102         for (int i = 0; i < childCount; i++) {
11103             PackageParser.Package childPkg = pkg.childPackages.get(i);
11104             ps = (PackageSetting) childPkg.mExtras;
11105             if (ps != null) {
11106                 removePackageLI(ps, chatty);
11107             }
11108         }
11109     }
11110
11111     void removePackageLI(PackageSetting ps, boolean chatty) {
11112         if (DEBUG_INSTALL) {
11113             if (chatty)
11114                 Log.d(TAG, "Removing package " + ps.name);
11115         }
11116
11117         // writer
11118         synchronized (mPackages) {
11119             mPackages.remove(ps.name);
11120             final PackageParser.Package pkg = ps.pkg;
11121             if (pkg != null) {
11122                 cleanPackageDataStructuresLILPw(pkg, chatty);
11123             }
11124         }
11125     }
11126
11127     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11128         if (DEBUG_INSTALL) {
11129             if (chatty)
11130                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11131         }
11132
11133         // writer
11134         synchronized (mPackages) {
11135             // Remove the parent package
11136             mPackages.remove(pkg.applicationInfo.packageName);
11137             cleanPackageDataStructuresLILPw(pkg, chatty);
11138
11139             // Remove the child packages
11140             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11141             for (int i = 0; i < childCount; i++) {
11142                 PackageParser.Package childPkg = pkg.childPackages.get(i);
11143                 mPackages.remove(childPkg.applicationInfo.packageName);
11144                 cleanPackageDataStructuresLILPw(childPkg, chatty);
11145             }
11146         }
11147     }
11148
11149     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11150         int N = pkg.providers.size();
11151         StringBuilder r = null;
11152         int i;
11153         for (i=0; i<N; i++) {
11154             PackageParser.Provider p = pkg.providers.get(i);
11155             mProviders.removeProvider(p);
11156             if (p.info.authority == null) {
11157
11158                 /* There was another ContentProvider with this authority when
11159                  * this app was installed so this authority is null,
11160                  * Ignore it as we don't have to unregister the provider.
11161                  */
11162                 continue;
11163             }
11164             String names[] = p.info.authority.split(";");
11165             for (int j = 0; j < names.length; j++) {
11166                 if (mProvidersByAuthority.get(names[j]) == p) {
11167                     mProvidersByAuthority.remove(names[j]);
11168                     if (DEBUG_REMOVE) {
11169                         if (chatty)
11170                             Log.d(TAG, "Unregistered content provider: " + names[j]
11171                                     + ", className = " + p.info.name + ", isSyncable = "
11172                                     + p.info.isSyncable);
11173                     }
11174                 }
11175             }
11176             if (DEBUG_REMOVE && chatty) {
11177                 if (r == null) {
11178                     r = new StringBuilder(256);
11179                 } else {
11180                     r.append(' ');
11181                 }
11182                 r.append(p.info.name);
11183             }
11184         }
11185         if (r != null) {
11186             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11187         }
11188
11189         N = pkg.services.size();
11190         r = null;
11191         for (i=0; i<N; i++) {
11192             PackageParser.Service s = pkg.services.get(i);
11193             mServices.removeService(s);
11194             if (chatty) {
11195                 if (r == null) {
11196                     r = new StringBuilder(256);
11197                 } else {
11198                     r.append(' ');
11199                 }
11200                 r.append(s.info.name);
11201             }
11202         }
11203         if (r != null) {
11204             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11205         }
11206
11207         N = pkg.receivers.size();
11208         r = null;
11209         for (i=0; i<N; i++) {
11210             PackageParser.Activity a = pkg.receivers.get(i);
11211             mReceivers.removeActivity(a, "receiver");
11212             if (DEBUG_REMOVE && chatty) {
11213                 if (r == null) {
11214                     r = new StringBuilder(256);
11215                 } else {
11216                     r.append(' ');
11217                 }
11218                 r.append(a.info.name);
11219             }
11220         }
11221         if (r != null) {
11222             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11223         }
11224
11225         N = pkg.activities.size();
11226         r = null;
11227         for (i=0; i<N; i++) {
11228             PackageParser.Activity a = pkg.activities.get(i);
11229             mActivities.removeActivity(a, "activity");
11230             if (DEBUG_REMOVE && chatty) {
11231                 if (r == null) {
11232                     r = new StringBuilder(256);
11233                 } else {
11234                     r.append(' ');
11235                 }
11236                 r.append(a.info.name);
11237             }
11238         }
11239         if (r != null) {
11240             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11241         }
11242
11243         N = pkg.permissions.size();
11244         r = null;
11245         for (i=0; i<N; i++) {
11246             PackageParser.Permission p = pkg.permissions.get(i);
11247             BasePermission bp = mSettings.mPermissions.get(p.info.name);
11248             if (bp == null) {
11249                 bp = mSettings.mPermissionTrees.get(p.info.name);
11250             }
11251             if (bp != null && bp.perm == p) {
11252                 bp.perm = null;
11253                 if (DEBUG_REMOVE && chatty) {
11254                     if (r == null) {
11255                         r = new StringBuilder(256);
11256                     } else {
11257                         r.append(' ');
11258                     }
11259                     r.append(p.info.name);
11260                 }
11261             }
11262             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11263                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11264                 if (appOpPkgs != null) {
11265                     appOpPkgs.remove(pkg.packageName);
11266                 }
11267             }
11268         }
11269         if (r != null) {
11270             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11271         }
11272
11273         N = pkg.requestedPermissions.size();
11274         r = null;
11275         for (i=0; i<N; i++) {
11276             String perm = pkg.requestedPermissions.get(i);
11277             BasePermission bp = mSettings.mPermissions.get(perm);
11278             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11279                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11280                 if (appOpPkgs != null) {
11281                     appOpPkgs.remove(pkg.packageName);
11282                     if (appOpPkgs.isEmpty()) {
11283                         mAppOpPermissionPackages.remove(perm);
11284                     }
11285                 }
11286             }
11287         }
11288         if (r != null) {
11289             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11290         }
11291
11292         N = pkg.instrumentation.size();
11293         r = null;
11294         for (i=0; i<N; i++) {
11295             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11296             mInstrumentation.remove(a.getComponentName());
11297             if (DEBUG_REMOVE && chatty) {
11298                 if (r == null) {
11299                     r = new StringBuilder(256);
11300                 } else {
11301                     r.append(' ');
11302                 }
11303                 r.append(a.info.name);
11304             }
11305         }
11306         if (r != null) {
11307             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11308         }
11309
11310         r = null;
11311         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11312             // Only system apps can hold shared libraries.
11313             if (pkg.libraryNames != null) {
11314                 for (i = 0; i < pkg.libraryNames.size(); i++) {
11315                     String name = pkg.libraryNames.get(i);
11316                     if (removeSharedLibraryLPw(name, 0)) {
11317                         if (DEBUG_REMOVE && chatty) {
11318                             if (r == null) {
11319                                 r = new StringBuilder(256);
11320                             } else {
11321                                 r.append(' ');
11322                             }
11323                             r.append(name);
11324                         }
11325                     }
11326                 }
11327             }
11328         }
11329
11330         r = null;
11331
11332         // Any package can hold static shared libraries.
11333         if (pkg.staticSharedLibName != null) {
11334             if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11335                 if (DEBUG_REMOVE && chatty) {
11336                     if (r == null) {
11337                         r = new StringBuilder(256);
11338                     } else {
11339                         r.append(' ');
11340                     }
11341                     r.append(pkg.staticSharedLibName);
11342                 }
11343             }
11344         }
11345
11346         if (r != null) {
11347             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11348         }
11349     }
11350
11351     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11352         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11353             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11354                 return true;
11355             }
11356         }
11357         return false;
11358     }
11359
11360     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11361     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11362     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11363
11364     private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11365         // Update the parent permissions
11366         updatePermissionsLPw(pkg.packageName, pkg, flags);
11367         // Update the child permissions
11368         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11369         for (int i = 0; i < childCount; i++) {
11370             PackageParser.Package childPkg = pkg.childPackages.get(i);
11371             updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11372         }
11373     }
11374
11375     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11376             int flags) {
11377         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11378         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11379     }
11380
11381     private void updatePermissionsLPw(String changingPkg,
11382             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11383         // Make sure there are no dangling permission trees.
11384         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11385         while (it.hasNext()) {
11386             final BasePermission bp = it.next();
11387             if (bp.packageSetting == null) {
11388                 // We may not yet have parsed the package, so just see if
11389                 // we still know about its settings.
11390                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11391             }
11392             if (bp.packageSetting == null) {
11393                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11394                         + " from package " + bp.sourcePackage);
11395                 it.remove();
11396             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11397                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11398                     Slog.i(TAG, "Removing old permission tree: " + bp.name
11399                             + " from package " + bp.sourcePackage);
11400                     flags |= UPDATE_PERMISSIONS_ALL;
11401                     it.remove();
11402                 }
11403             }
11404         }
11405
11406         // Make sure all dynamic permissions have been assigned to a package,
11407         // and make sure there are no dangling permissions.
11408         it = mSettings.mPermissions.values().iterator();
11409         while (it.hasNext()) {
11410             final BasePermission bp = it.next();
11411             if (bp.type == BasePermission.TYPE_DYNAMIC) {
11412                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11413                         + bp.name + " pkg=" + bp.sourcePackage
11414                         + " info=" + bp.pendingInfo);
11415                 if (bp.packageSetting == null && bp.pendingInfo != null) {
11416                     final BasePermission tree = findPermissionTreeLP(bp.name);
11417                     if (tree != null && tree.perm != null) {
11418                         bp.packageSetting = tree.packageSetting;
11419                         bp.perm = new PackageParser.Permission(tree.perm.owner,
11420                                 new PermissionInfo(bp.pendingInfo));
11421                         bp.perm.info.packageName = tree.perm.info.packageName;
11422                         bp.perm.info.name = bp.name;
11423                         bp.uid = tree.uid;
11424                     }
11425                 }
11426             }
11427             if (bp.packageSetting == null) {
11428                 // We may not yet have parsed the package, so just see if
11429                 // we still know about its settings.
11430                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11431             }
11432             if (bp.packageSetting == null) {
11433                 Slog.w(TAG, "Removing dangling permission: " + bp.name
11434                         + " from package " + bp.sourcePackage);
11435                 it.remove();
11436             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11437                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11438                     Slog.i(TAG, "Removing old permission: " + bp.name
11439                             + " from package " + bp.sourcePackage);
11440                     flags |= UPDATE_PERMISSIONS_ALL;
11441                     it.remove();
11442                 }
11443             }
11444         }
11445
11446         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11447         // Now update the permissions for all packages, in particular
11448         // replace the granted permissions of the system packages.
11449         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11450             for (PackageParser.Package pkg : mPackages.values()) {
11451                 if (pkg != pkgInfo) {
11452                     // Only replace for packages on requested volume
11453                     final String volumeUuid = getVolumeUuidForPackage(pkg);
11454                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11455                             && Objects.equals(replaceVolumeUuid, volumeUuid);
11456                     grantPermissionsLPw(pkg, replace, changingPkg);
11457                 }
11458             }
11459         }
11460
11461         if (pkgInfo != null) {
11462             // Only replace for packages on requested volume
11463             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11464             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11465                     && Objects.equals(replaceVolumeUuid, volumeUuid);
11466             grantPermissionsLPw(pkgInfo, replace, changingPkg);
11467         }
11468         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11469     }
11470
11471     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11472             String packageOfInterest) {
11473         // IMPORTANT: There are two types of permissions: install and runtime.
11474         // Install time permissions are granted when the app is installed to
11475         // all device users and users added in the future. Runtime permissions
11476         // are granted at runtime explicitly to specific users. Normal and signature
11477         // protected permissions are install time permissions. Dangerous permissions
11478         // are install permissions if the app's target SDK is Lollipop MR1 or older,
11479         // otherwise they are runtime permissions. This function does not manage
11480         // runtime permissions except for the case an app targeting Lollipop MR1
11481         // being upgraded to target a newer SDK, in which case dangerous permissions
11482         // are transformed from install time to runtime ones.
11483
11484         final PackageSetting ps = (PackageSetting) pkg.mExtras;
11485         if (ps == null) {
11486             return;
11487         }
11488
11489         PermissionsState permissionsState = ps.getPermissionsState();
11490         PermissionsState origPermissions = permissionsState;
11491
11492         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11493
11494         boolean runtimePermissionsRevoked = false;
11495         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11496
11497         boolean changedInstallPermission = false;
11498
11499         if (replace) {
11500             ps.installPermissionsFixed = false;
11501             if (!ps.isSharedUser()) {
11502                 origPermissions = new PermissionsState(permissionsState);
11503                 permissionsState.reset();
11504             } else {
11505                 // We need to know only about runtime permission changes since the
11506                 // calling code always writes the install permissions state but
11507                 // the runtime ones are written only if changed. The only cases of
11508                 // changed runtime permissions here are promotion of an install to
11509                 // runtime and revocation of a runtime from a shared user.
11510                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11511                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
11512                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11513                     runtimePermissionsRevoked = true;
11514                 }
11515             }
11516         }
11517
11518         permissionsState.setGlobalGids(mGlobalGids);
11519
11520         final int N = pkg.requestedPermissions.size();
11521         for (int i=0; i<N; i++) {
11522             final String name = pkg.requestedPermissions.get(i);
11523             final BasePermission bp = mSettings.mPermissions.get(name);
11524             final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11525                     >= Build.VERSION_CODES.M;
11526
11527             if (DEBUG_INSTALL) {
11528                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11529             }
11530
11531             if (bp == null || bp.packageSetting == null) {
11532                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11533                     Slog.w(TAG, "Unknown permission " + name
11534                             + " in package " + pkg.packageName);
11535                 }
11536                 continue;
11537             }
11538
11539
11540             // Limit ephemeral apps to ephemeral allowed permissions.
11541             if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11542                 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11543                         + pkg.packageName);
11544                 continue;
11545             }
11546
11547             if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
11548                 Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
11549                         + pkg.packageName);
11550                 continue;
11551             }
11552
11553             final String perm = bp.name;
11554             boolean allowedSig = false;
11555             int grant = GRANT_DENIED;
11556
11557             // Keep track of app op permissions.
11558             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11559                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11560                 if (pkgs == null) {
11561                     pkgs = new ArraySet<>();
11562                     mAppOpPermissionPackages.put(bp.name, pkgs);
11563                 }
11564                 pkgs.add(pkg.packageName);
11565             }
11566
11567             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11568             switch (level) {
11569                 case PermissionInfo.PROTECTION_NORMAL: {
11570                     // For all apps normal permissions are install time ones.
11571                     grant = GRANT_INSTALL;
11572                 } break;
11573
11574                 case PermissionInfo.PROTECTION_DANGEROUS: {
11575                     // If a permission review is required for legacy apps we represent
11576                     // their permissions as always granted runtime ones since we need
11577                     // to keep the review required permission flag per user while an
11578                     // install permission's state is shared across all users.
11579                     if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11580                         // For legacy apps dangerous permissions are install time ones.
11581                         grant = GRANT_INSTALL;
11582                     } else if (origPermissions.hasInstallPermission(bp.name)) {
11583                         // For legacy apps that became modern, install becomes runtime.
11584                         grant = GRANT_UPGRADE;
11585                     } else if (mPromoteSystemApps
11586                             && isSystemApp(ps)
11587                             && mExistingSystemPackages.contains(ps.name)) {
11588                         // For legacy system apps, install becomes runtime.
11589                         // We cannot check hasInstallPermission() for system apps since those
11590                         // permissions were granted implicitly and not persisted pre-M.
11591                         grant = GRANT_UPGRADE;
11592                     } else {
11593                         // For modern apps keep runtime permissions unchanged.
11594                         grant = GRANT_RUNTIME;
11595                     }
11596                 } break;
11597
11598                 case PermissionInfo.PROTECTION_SIGNATURE: {
11599                     // For all apps signature permissions are install time ones.
11600                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
11601                     if (allowedSig) {
11602                         grant = GRANT_INSTALL;
11603                     }
11604                 } break;
11605             }
11606
11607             if (DEBUG_INSTALL) {
11608                 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
11609             }
11610
11611             if (grant != GRANT_DENIED) {
11612                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
11613                     // If this is an existing, non-system package, then
11614                     // we can't add any new permissions to it.
11615                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
11616                         // Except...  if this is a permission that was added
11617                         // to the platform (note: need to only do this when
11618                         // updating the platform).
11619                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
11620                             grant = GRANT_DENIED;
11621                         }
11622                     }
11623                 }
11624
11625                 switch (grant) {
11626                     case GRANT_INSTALL: {
11627                         // Revoke this as runtime permission to handle the case of
11628                         // a runtime permission being downgraded to an install one.
11629                         // Also in permission review mode we keep dangerous permissions
11630                         // for legacy apps
11631                         for (int userId : UserManagerService.getInstance().getUserIds()) {
11632                             if (origPermissions.getRuntimePermissionState(
11633                                     bp.name, userId) != null) {
11634                                 // Revoke the runtime permission and clear the flags.
11635                                 origPermissions.revokeRuntimePermission(bp, userId);
11636                                 origPermissions.updatePermissionFlags(bp, userId,
11637                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
11638                                 // If we revoked a permission permission, we have to write.
11639                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11640                                         changedRuntimePermissionUserIds, userId);
11641                             }
11642                         }
11643                         // Grant an install permission.
11644                         if (permissionsState.grantInstallPermission(bp) !=
11645                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
11646                             changedInstallPermission = true;
11647                         }
11648                     } break;
11649
11650                     case GRANT_RUNTIME: {
11651                         // Grant previously granted runtime permissions.
11652                         for (int userId : UserManagerService.getInstance().getUserIds()) {
11653                             PermissionState permissionState = origPermissions
11654                                     .getRuntimePermissionState(bp.name, userId);
11655                             int flags = permissionState != null
11656                                     ? permissionState.getFlags() : 0;
11657                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
11658                                 // Don't propagate the permission in a permission review mode if
11659                                 // the former was revoked, i.e. marked to not propagate on upgrade.
11660                                 // Note that in a permission review mode install permissions are
11661                                 // represented as constantly granted runtime ones since we need to
11662                                 // keep a per user state associated with the permission. Also the
11663                                 // revoke on upgrade flag is no longer applicable and is reset.
11664                                 final boolean revokeOnUpgrade = (flags & PackageManager
11665                                         .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
11666                                 if (revokeOnUpgrade) {
11667                                     flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
11668                                     // Since we changed the flags, we have to write.
11669                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11670                                             changedRuntimePermissionUserIds, userId);
11671                                 }
11672                                 if (!mPermissionReviewRequired || !revokeOnUpgrade) {
11673                                     if (permissionsState.grantRuntimePermission(bp, userId) ==
11674                                             PermissionsState.PERMISSION_OPERATION_FAILURE) {
11675                                         // If we cannot put the permission as it was,
11676                                         // we have to write.
11677                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11678                                                 changedRuntimePermissionUserIds, userId);
11679                                     }
11680                                 }
11681
11682                                 // If the app supports runtime permissions no need for a review.
11683                                 if (mPermissionReviewRequired
11684                                         && appSupportsRuntimePermissions
11685                                         && (flags & PackageManager
11686                                                 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
11687                                     flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
11688                                     // Since we changed the flags, we have to write.
11689                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11690                                             changedRuntimePermissionUserIds, userId);
11691                                 }
11692                             } else if (mPermissionReviewRequired
11693                                     && !appSupportsRuntimePermissions) {
11694                                 // For legacy apps that need a permission review, every new
11695                                 // runtime permission is granted but it is pending a review.
11696                                 // We also need to review only platform defined runtime
11697                                 // permissions as these are the only ones the platform knows
11698                                 // how to disable the API to simulate revocation as legacy
11699                                 // apps don't expect to run with revoked permissions.
11700                                 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
11701                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
11702                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
11703                                         // We changed the flags, hence have to write.
11704                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11705                                                 changedRuntimePermissionUserIds, userId);
11706                                     }
11707                                 }
11708                                 if (permissionsState.grantRuntimePermission(bp, userId)
11709                                         != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11710                                     // We changed the permission, hence have to write.
11711                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11712                                             changedRuntimePermissionUserIds, userId);
11713                                 }
11714                             }
11715                             // Propagate the permission flags.
11716                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
11717                         }
11718                     } break;
11719
11720                     case GRANT_UPGRADE: {
11721                         // Grant runtime permissions for a previously held install permission.
11722                         PermissionState permissionState = origPermissions
11723                                 .getInstallPermissionState(bp.name);
11724                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
11725
11726                         if (origPermissions.revokeInstallPermission(bp)
11727                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11728                             // We will be transferring the permission flags, so clear them.
11729                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
11730                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
11731                             changedInstallPermission = true;
11732                         }
11733
11734                         // If the permission is not to be promoted to runtime we ignore it and
11735                         // also its other flags as they are not applicable to install permissions.
11736                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
11737                             for (int userId : currentUserIds) {
11738                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
11739                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
11740                                     // Transfer the permission flags.
11741                                     permissionsState.updatePermissionFlags(bp, userId,
11742                                             flags, flags);
11743                                     // If we granted the permission, we have to write.
11744                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11745                                             changedRuntimePermissionUserIds, userId);
11746                                 }
11747                             }
11748                         }
11749                     } break;
11750
11751                     default: {
11752                         if (packageOfInterest == null
11753                                 || packageOfInterest.equals(pkg.packageName)) {
11754                             Slog.w(TAG, "Not granting permission " + perm
11755                                     + " to package " + pkg.packageName
11756                                     + " because it was previously installed without");
11757                         }
11758                     } break;
11759                 }
11760             } else {
11761                 if (permissionsState.revokeInstallPermission(bp) !=
11762                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
11763                     // Also drop the permission flags.
11764                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
11765                             PackageManager.MASK_PERMISSION_FLAGS, 0);
11766                     changedInstallPermission = true;
11767                     Slog.i(TAG, "Un-granting permission " + perm
11768                             + " from package " + pkg.packageName
11769                             + " (protectionLevel=" + bp.protectionLevel
11770                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11771                             + ")");
11772                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
11773                     // Don't print warning for app op permissions, since it is fine for them
11774                     // not to be granted, there is a UI for the user to decide.
11775                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11776                         Slog.w(TAG, "Not granting permission " + perm
11777                                 + " to package " + pkg.packageName
11778                                 + " (protectionLevel=" + bp.protectionLevel
11779                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11780                                 + ")");
11781                     }
11782                 }
11783             }
11784         }
11785
11786         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
11787                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
11788             // This is the first that we have heard about this package, so the
11789             // permissions we have now selected are fixed until explicitly
11790             // changed.
11791             ps.installPermissionsFixed = true;
11792         }
11793
11794         // Persist the runtime permissions state for users with changes. If permissions
11795         // were revoked because no app in the shared user declares them we have to
11796         // write synchronously to avoid losing runtime permissions state.
11797         for (int userId : changedRuntimePermissionUserIds) {
11798             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
11799         }
11800     }
11801
11802     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
11803         boolean allowed = false;
11804         final int NP = PackageParser.NEW_PERMISSIONS.length;
11805         for (int ip=0; ip<NP; ip++) {
11806             final PackageParser.NewPermissionInfo npi
11807                     = PackageParser.NEW_PERMISSIONS[ip];
11808             if (npi.name.equals(perm)
11809                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
11810                 allowed = true;
11811                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
11812                         + pkg.packageName);
11813                 break;
11814             }
11815         }
11816         return allowed;
11817     }
11818
11819     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
11820             BasePermission bp, PermissionsState origPermissions) {
11821         boolean privilegedPermission = (bp.protectionLevel
11822                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
11823         boolean privappPermissionsDisable =
11824                 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
11825         boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
11826         boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
11827         if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
11828                 && !platformPackage && platformPermission) {
11829             ArraySet<String> wlPermissions = SystemConfig.getInstance()
11830                     .getPrivAppPermissions(pkg.packageName);
11831             boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
11832             if (!whitelisted) {
11833                 Slog.w(TAG, "Privileged permission " + perm + " for package "
11834                         + pkg.packageName + " - not in privapp-permissions whitelist");
11835                 // Only report violations for apps on system image
11836                 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
11837                     if (mPrivappPermissionsViolations == null) {
11838                         mPrivappPermissionsViolations = new ArraySet<>();
11839                     }
11840                     mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
11841                 }
11842                 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
11843                     return false;
11844                 }
11845             }
11846         }
11847         boolean allowed = (compareSignatures(
11848                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
11849                         == PackageManager.SIGNATURE_MATCH)
11850                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
11851                         == PackageManager.SIGNATURE_MATCH);
11852         if (!allowed && privilegedPermission) {
11853             if (isSystemApp(pkg)) {
11854                 // For updated system applications, a system permission
11855                 // is granted only if it had been defined by the original application.
11856                 if (pkg.isUpdatedSystemApp()) {
11857                     final PackageSetting sysPs = mSettings
11858                             .getDisabledSystemPkgLPr(pkg.packageName);
11859                     if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
11860                         // If the original was granted this permission, we take
11861                         // that grant decision as read and propagate it to the
11862                         // update.
11863                         if (sysPs.isPrivileged()) {
11864                             allowed = true;
11865                         }
11866                     } else {
11867                         // The system apk may have been updated with an older
11868                         // version of the one on the data partition, but which
11869                         // granted a new system permission that it didn't have
11870                         // before.  In this case we do want to allow the app to
11871                         // now get the new permission if the ancestral apk is
11872                         // privileged to get it.
11873                         if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
11874                             for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
11875                                 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
11876                                     allowed = true;
11877                                     break;
11878                                 }
11879                             }
11880                         }
11881                         // Also if a privileged parent package on the system image or any of
11882                         // its children requested a privileged permission, the updated child
11883                         // packages can also get the permission.
11884                         if (pkg.parentPackage != null) {
11885                             final PackageSetting disabledSysParentPs = mSettings
11886                                     .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
11887                             if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
11888                                     && disabledSysParentPs.isPrivileged()) {
11889                                 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
11890                                     allowed = true;
11891                                 } else if (disabledSysParentPs.pkg.childPackages != null) {
11892                                     final int count = disabledSysParentPs.pkg.childPackages.size();
11893                                     for (int i = 0; i < count; i++) {
11894                                         PackageParser.Package disabledSysChildPkg =
11895                                                 disabledSysParentPs.pkg.childPackages.get(i);
11896                                         if (isPackageRequestingPermission(disabledSysChildPkg,
11897                                                 perm)) {
11898                                             allowed = true;
11899                                             break;
11900                                         }
11901                                     }
11902                                 }
11903                             }
11904                         }
11905                     }
11906                 } else {
11907                     allowed = isPrivilegedApp(pkg);
11908                 }
11909             }
11910         }
11911         if (!allowed) {
11912             if (!allowed && (bp.protectionLevel
11913                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
11914                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
11915                 // If this was a previously normal/dangerous permission that got moved
11916                 // to a system permission as part of the runtime permission redesign, then
11917                 // we still want to blindly grant it to old apps.
11918                 allowed = true;
11919             }
11920             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
11921                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
11922                 // If this permission is to be granted to the system installer and
11923                 // this app is an installer, then it gets the permission.
11924                 allowed = true;
11925             }
11926             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
11927                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
11928                 // If this permission is to be granted to the system verifier and
11929                 // this app is a verifier, then it gets the permission.
11930                 allowed = true;
11931             }
11932             if (!allowed && (bp.protectionLevel
11933                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
11934                     && isSystemApp(pkg)) {
11935                 // Any pre-installed system app is allowed to get this permission.
11936                 allowed = true;
11937             }
11938             if (!allowed && (bp.protectionLevel
11939                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
11940                 // For development permissions, a development permission
11941                 // is granted only if it was already granted.
11942                 allowed = origPermissions.hasInstallPermission(perm);
11943             }
11944             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
11945                     && pkg.packageName.equals(mSetupWizardPackage)) {
11946                 // If this permission is to be granted to the system setup wizard and
11947                 // this app is a setup wizard, then it gets the permission.
11948                 allowed = true;
11949             }
11950         }
11951         return allowed;
11952     }
11953
11954     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
11955         final int permCount = pkg.requestedPermissions.size();
11956         for (int j = 0; j < permCount; j++) {
11957             String requestedPermission = pkg.requestedPermissions.get(j);
11958             if (permission.equals(requestedPermission)) {
11959                 return true;
11960             }
11961         }
11962         return false;
11963     }
11964
11965     final class ActivityIntentResolver
11966             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11967         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11968                 boolean defaultOnly, int userId) {
11969             if (!sUserManager.exists(userId)) return null;
11970             mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11971             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11972         }
11973
11974         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11975                 int userId) {
11976             if (!sUserManager.exists(userId)) return null;
11977             mFlags = flags;
11978             return super.queryIntent(intent, resolvedType,
11979                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11980                     userId);
11981         }
11982
11983         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11984                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11985             if (!sUserManager.exists(userId)) return null;
11986             if (packageActivities == null) {
11987                 return null;
11988             }
11989             mFlags = flags;
11990             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11991             final int N = packageActivities.size();
11992             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11993                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11994
11995             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11996             for (int i = 0; i < N; ++i) {
11997                 intentFilters = packageActivities.get(i).intents;
11998                 if (intentFilters != null && intentFilters.size() > 0) {
11999                     PackageParser.ActivityIntentInfo[] array =
12000                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
12001                     intentFilters.toArray(array);
12002                     listCut.add(array);
12003                 }
12004             }
12005             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12006         }
12007
12008         /**
12009          * Finds a privileged activity that matches the specified activity names.
12010          */
12011         private PackageParser.Activity findMatchingActivity(
12012                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12013             for (PackageParser.Activity sysActivity : activityList) {
12014                 if (sysActivity.info.name.equals(activityInfo.name)) {
12015                     return sysActivity;
12016                 }
12017                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12018                     return sysActivity;
12019                 }
12020                 if (sysActivity.info.targetActivity != null) {
12021                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12022                         return sysActivity;
12023                     }
12024                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12025                         return sysActivity;
12026                     }
12027                 }
12028             }
12029             return null;
12030         }
12031
12032         public class IterGenerator<E> {
12033             public Iterator<E> generate(ActivityIntentInfo info) {
12034                 return null;
12035             }
12036         }
12037
12038         public class ActionIterGenerator extends IterGenerator<String> {
12039             @Override
12040             public Iterator<String> generate(ActivityIntentInfo info) {
12041                 return info.actionsIterator();
12042             }
12043         }
12044
12045         public class CategoriesIterGenerator extends IterGenerator<String> {
12046             @Override
12047             public Iterator<String> generate(ActivityIntentInfo info) {
12048                 return info.categoriesIterator();
12049             }
12050         }
12051
12052         public class SchemesIterGenerator extends IterGenerator<String> {
12053             @Override
12054             public Iterator<String> generate(ActivityIntentInfo info) {
12055                 return info.schemesIterator();
12056             }
12057         }
12058
12059         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12060             @Override
12061             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12062                 return info.authoritiesIterator();
12063             }
12064         }
12065
12066         /**
12067          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12068          * MODIFIED. Do not pass in a list that should not be changed.
12069          */
12070         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12071                 IterGenerator<T> generator, Iterator<T> searchIterator) {
12072             // loop through the set of actions; every one must be found in the intent filter
12073             while (searchIterator.hasNext()) {
12074                 // we must have at least one filter in the list to consider a match
12075                 if (intentList.size() == 0) {
12076                     break;
12077                 }
12078
12079                 final T searchAction = searchIterator.next();
12080
12081                 // loop through the set of intent filters
12082                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12083                 while (intentIter.hasNext()) {
12084                     final ActivityIntentInfo intentInfo = intentIter.next();
12085                     boolean selectionFound = false;
12086
12087                     // loop through the intent filter's selection criteria; at least one
12088                     // of them must match the searched criteria
12089                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12090                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12091                         final T intentSelection = intentSelectionIter.next();
12092                         if (intentSelection != null && intentSelection.equals(searchAction)) {
12093                             selectionFound = true;
12094                             break;
12095                         }
12096                     }
12097
12098                     // the selection criteria wasn't found in this filter's set; this filter
12099                     // is not a potential match
12100                     if (!selectionFound) {
12101                         intentIter.remove();
12102                     }
12103                 }
12104             }
12105         }
12106
12107         private boolean isProtectedAction(ActivityIntentInfo filter) {
12108             final Iterator<String> actionsIter = filter.actionsIterator();
12109             while (actionsIter != null && actionsIter.hasNext()) {
12110                 final String filterAction = actionsIter.next();
12111                 if (PROTECTED_ACTIONS.contains(filterAction)) {
12112                     return true;
12113                 }
12114             }
12115             return false;
12116         }
12117
12118         /**
12119          * Adjusts the priority of the given intent filter according to policy.
12120          * <p>
12121          * <ul>
12122          * <li>The priority for non privileged applications is capped to '0'</li>
12123          * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12124          * <li>The priority for unbundled updates to privileged applications is capped to the
12125          *      priority defined on the system partition</li>
12126          * </ul>
12127          * <p>
12128          * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12129          * allowed to obtain any priority on any action.
12130          */
12131         private void adjustPriority(
12132                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12133             // nothing to do; priority is fine as-is
12134             if (intent.getPriority() <= 0) {
12135                 return;
12136             }
12137
12138             final ActivityInfo activityInfo = intent.activity.info;
12139             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12140
12141             final boolean privilegedApp =
12142                     ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12143             if (!privilegedApp) {
12144                 // non-privileged applications can never define a priority >0
12145                 Slog.w(TAG, "Non-privileged app; cap priority to 0;"
12146                         + " package: " + applicationInfo.packageName
12147                         + " activity: " + intent.activity.className
12148                         + " origPrio: " + intent.getPriority());
12149                 intent.setPriority(0);
12150                 return;
12151             }
12152
12153             if (systemActivities == null) {
12154                 // the system package is not disabled; we're parsing the system partition
12155                 if (isProtectedAction(intent)) {
12156                     if (mDeferProtectedFilters) {
12157                         // We can't deal with these just yet. No component should ever obtain a
12158                         // >0 priority for a protected actions, with ONE exception -- the setup
12159                         // wizard. The setup wizard, however, cannot be known until we're able to
12160                         // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12161                         // until all intent filters have been processed. Chicken, meet egg.
12162                         // Let the filter temporarily have a high priority and rectify the
12163                         // priorities after all system packages have been scanned.
12164                         mProtectedFilters.add(intent);
12165                         if (DEBUG_FILTERS) {
12166                             Slog.i(TAG, "Protected action; save for later;"
12167                                     + " package: " + applicationInfo.packageName
12168                                     + " activity: " + intent.activity.className
12169                                     + " origPrio: " + intent.getPriority());
12170                         }
12171                         return;
12172                     } else {
12173                         if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12174                             Slog.i(TAG, "No setup wizard;"
12175                                 + " All protected intents capped to priority 0");
12176                         }
12177                         if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12178                             if (DEBUG_FILTERS) {
12179                                 Slog.i(TAG, "Found setup wizard;"
12180                                     + " allow priority " + intent.getPriority() + ";"
12181                                     + " package: " + intent.activity.info.packageName
12182                                     + " activity: " + intent.activity.className
12183                                     + " priority: " + intent.getPriority());
12184                             }
12185                             // setup wizard gets whatever it wants
12186                             return;
12187                         }
12188                         Slog.w(TAG, "Protected action; cap priority to 0;"
12189                                 + " package: " + intent.activity.info.packageName
12190                                 + " activity: " + intent.activity.className
12191                                 + " origPrio: " + intent.getPriority());
12192                         intent.setPriority(0);
12193                         return;
12194                     }
12195                 }
12196                 // privileged apps on the system image get whatever priority they request
12197                 return;
12198             }
12199
12200             // privileged app unbundled update ... try to find the same activity
12201             final PackageParser.Activity foundActivity =
12202                     findMatchingActivity(systemActivities, activityInfo);
12203             if (foundActivity == null) {
12204                 // this is a new activity; it cannot obtain >0 priority
12205                 if (DEBUG_FILTERS) {
12206                     Slog.i(TAG, "New activity; cap priority to 0;"
12207                             + " package: " + applicationInfo.packageName
12208                             + " activity: " + intent.activity.className
12209                             + " origPrio: " + intent.getPriority());
12210                 }
12211                 intent.setPriority(0);
12212                 return;
12213             }
12214
12215             // found activity, now check for filter equivalence
12216
12217             // a shallow copy is enough; we modify the list, not its contents
12218             final List<ActivityIntentInfo> intentListCopy =
12219                     new ArrayList<>(foundActivity.intents);
12220             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12221
12222             // find matching action subsets
12223             final Iterator<String> actionsIterator = intent.actionsIterator();
12224             if (actionsIterator != null) {
12225                 getIntentListSubset(
12226                         intentListCopy, new ActionIterGenerator(), actionsIterator);
12227                 if (intentListCopy.size() == 0) {
12228                     // no more intents to match; we're not equivalent
12229                     if (DEBUG_FILTERS) {
12230                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
12231                                 + " package: " + applicationInfo.packageName
12232                                 + " activity: " + intent.activity.className
12233                                 + " origPrio: " + intent.getPriority());
12234                     }
12235                     intent.setPriority(0);
12236                     return;
12237                 }
12238             }
12239
12240             // find matching category subsets
12241             final Iterator<String> categoriesIterator = intent.categoriesIterator();
12242             if (categoriesIterator != null) {
12243                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12244                         categoriesIterator);
12245                 if (intentListCopy.size() == 0) {
12246                     // no more intents to match; we're not equivalent
12247                     if (DEBUG_FILTERS) {
12248                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
12249                                 + " package: " + applicationInfo.packageName
12250                                 + " activity: " + intent.activity.className
12251                                 + " origPrio: " + intent.getPriority());
12252                     }
12253                     intent.setPriority(0);
12254                     return;
12255                 }
12256             }
12257
12258             // find matching schemes subsets
12259             final Iterator<String> schemesIterator = intent.schemesIterator();
12260             if (schemesIterator != null) {
12261                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12262                         schemesIterator);
12263                 if (intentListCopy.size() == 0) {
12264                     // no more intents to match; we're not equivalent
12265                     if (DEBUG_FILTERS) {
12266                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12267                                 + " package: " + applicationInfo.packageName
12268                                 + " activity: " + intent.activity.className
12269                                 + " origPrio: " + intent.getPriority());
12270                     }
12271                     intent.setPriority(0);
12272                     return;
12273                 }
12274             }
12275
12276             // find matching authorities subsets
12277             final Iterator<IntentFilter.AuthorityEntry>
12278                     authoritiesIterator = intent.authoritiesIterator();
12279             if (authoritiesIterator != null) {
12280                 getIntentListSubset(intentListCopy,
12281                         new AuthoritiesIterGenerator(),
12282                         authoritiesIterator);
12283                 if (intentListCopy.size() == 0) {
12284                     // no more intents to match; we're not equivalent
12285                     if (DEBUG_FILTERS) {
12286                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12287                                 + " package: " + applicationInfo.packageName
12288                                 + " activity: " + intent.activity.className
12289                                 + " origPrio: " + intent.getPriority());
12290                     }
12291                     intent.setPriority(0);
12292                     return;
12293                 }
12294             }
12295
12296             // we found matching filter(s); app gets the max priority of all intents
12297             int cappedPriority = 0;
12298             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12299                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12300             }
12301             if (intent.getPriority() > cappedPriority) {
12302                 if (DEBUG_FILTERS) {
12303                     Slog.i(TAG, "Found matching filter(s);"
12304                             + " cap priority to " + cappedPriority + ";"
12305                             + " package: " + applicationInfo.packageName
12306                             + " activity: " + intent.activity.className
12307                             + " origPrio: " + intent.getPriority());
12308                 }
12309                 intent.setPriority(cappedPriority);
12310                 return;
12311             }
12312             // all this for nothing; the requested priority was <= what was on the system
12313         }
12314
12315         public final void addActivity(PackageParser.Activity a, String type) {
12316             mActivities.put(a.getComponentName(), a);
12317             if (DEBUG_SHOW_INFO)
12318                 Log.v(
12319                 TAG, "  " + type + " " +
12320                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12321             if (DEBUG_SHOW_INFO)
12322                 Log.v(TAG, "    Class=" + a.info.name);
12323             final int NI = a.intents.size();
12324             for (int j=0; j<NI; j++) {
12325                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12326                 if ("activity".equals(type)) {
12327                     final PackageSetting ps =
12328                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12329                     final List<PackageParser.Activity> systemActivities =
12330                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
12331                     adjustPriority(systemActivities, intent);
12332                 }
12333                 if (DEBUG_SHOW_INFO) {
12334                     Log.v(TAG, "    IntentFilter:");
12335                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12336                 }
12337                 if (!intent.debugCheck()) {
12338                     Log.w(TAG, "==> For Activity " + a.info.name);
12339                 }
12340                 addFilter(intent);
12341             }
12342         }
12343
12344         public final void removeActivity(PackageParser.Activity a, String type) {
12345             mActivities.remove(a.getComponentName());
12346             if (DEBUG_SHOW_INFO) {
12347                 Log.v(TAG, "  " + type + " "
12348                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12349                                 : a.info.name) + ":");
12350                 Log.v(TAG, "    Class=" + a.info.name);
12351             }
12352             final int NI = a.intents.size();
12353             for (int j=0; j<NI; j++) {
12354                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12355                 if (DEBUG_SHOW_INFO) {
12356                     Log.v(TAG, "    IntentFilter:");
12357                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12358                 }
12359                 removeFilter(intent);
12360             }
12361         }
12362
12363         @Override
12364         protected boolean allowFilterResult(
12365                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12366             ActivityInfo filterAi = filter.activity.info;
12367             for (int i=dest.size()-1; i>=0; i--) {
12368                 ActivityInfo destAi = dest.get(i).activityInfo;
12369                 if (destAi.name == filterAi.name
12370                         && destAi.packageName == filterAi.packageName) {
12371                     return false;
12372                 }
12373             }
12374             return true;
12375         }
12376
12377         @Override
12378         protected ActivityIntentInfo[] newArray(int size) {
12379             return new ActivityIntentInfo[size];
12380         }
12381
12382         @Override
12383         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12384             if (!sUserManager.exists(userId)) return true;
12385             PackageParser.Package p = filter.activity.owner;
12386             if (p != null) {
12387                 PackageSetting ps = (PackageSetting)p.mExtras;
12388                 if (ps != null) {
12389                     // System apps are never considered stopped for purposes of
12390                     // filtering, because there may be no way for the user to
12391                     // actually re-launch them.
12392                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12393                             && ps.getStopped(userId);
12394                 }
12395             }
12396             return false;
12397         }
12398
12399         @Override
12400         protected boolean isPackageForFilter(String packageName,
12401                 PackageParser.ActivityIntentInfo info) {
12402             return packageName.equals(info.activity.owner.packageName);
12403         }
12404
12405         @Override
12406         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12407                 int match, int userId) {
12408             if (!sUserManager.exists(userId)) return null;
12409             if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12410                 return null;
12411             }
12412             final PackageParser.Activity activity = info.activity;
12413             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12414             if (ps == null) {
12415                 return null;
12416             }
12417             final PackageUserState userState = ps.readUserState(userId);
12418             ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
12419             if (ai == null) {
12420                 return null;
12421             }
12422             final boolean matchVisibleToInstantApp =
12423                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12424             final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12425             // throw out filters that aren't visible to ephemeral apps
12426             if (matchVisibleToInstantApp
12427                     && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12428                 return null;
12429             }
12430             // throw out ephemeral filters if we're not explicitly requesting them
12431             if (!isInstantApp && userState.instantApp) {
12432                 return null;
12433             }
12434             // throw out instant app filters if updates are available; will trigger
12435             // instant app resolution
12436             if (userState.instantApp && ps.isUpdateAvailable()) {
12437                 return null;
12438             }
12439             final ResolveInfo res = new ResolveInfo();
12440             res.activityInfo = ai;
12441             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12442                 res.filter = info;
12443             }
12444             if (info != null) {
12445                 res.handleAllWebDataURI = info.handleAllWebDataURI();
12446             }
12447             res.priority = info.getPriority();
12448             res.preferredOrder = activity.owner.mPreferredOrder;
12449             //System.out.println("Result: " + res.activityInfo.className +
12450             //                   " = " + res.priority);
12451             res.match = match;
12452             res.isDefault = info.hasDefault;
12453             res.labelRes = info.labelRes;
12454             res.nonLocalizedLabel = info.nonLocalizedLabel;
12455             if (userNeedsBadging(userId)) {
12456                 res.noResourceId = true;
12457             } else {
12458                 res.icon = info.icon;
12459             }
12460             res.iconResourceId = info.icon;
12461             res.system = res.activityInfo.applicationInfo.isSystemApp();
12462             res.instantAppAvailable = userState.instantApp;
12463             return res;
12464         }
12465
12466         @Override
12467         protected void sortResults(List<ResolveInfo> results) {
12468             Collections.sort(results, mResolvePrioritySorter);
12469         }
12470
12471         @Override
12472         protected void dumpFilter(PrintWriter out, String prefix,
12473                 PackageParser.ActivityIntentInfo filter) {
12474             out.print(prefix); out.print(
12475                     Integer.toHexString(System.identityHashCode(filter.activity)));
12476                     out.print(' ');
12477                     filter.activity.printComponentShortName(out);
12478                     out.print(" filter ");
12479                     out.println(Integer.toHexString(System.identityHashCode(filter)));
12480         }
12481
12482         @Override
12483         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12484             return filter.activity;
12485         }
12486
12487         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12488             PackageParser.Activity activity = (PackageParser.Activity)label;
12489             out.print(prefix); out.print(
12490                     Integer.toHexString(System.identityHashCode(activity)));
12491                     out.print(' ');
12492                     activity.printComponentShortName(out);
12493             if (count > 1) {
12494                 out.print(" ("); out.print(count); out.print(" filters)");
12495             }
12496             out.println();
12497         }
12498
12499         // Keys are String (activity class name), values are Activity.
12500         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12501                 = new ArrayMap<ComponentName, PackageParser.Activity>();
12502         private int mFlags;
12503     }
12504
12505     private final class ServiceIntentResolver
12506             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12507         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12508                 boolean defaultOnly, int userId) {
12509             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12510             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12511         }
12512
12513         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12514                 int userId) {
12515             if (!sUserManager.exists(userId)) return null;
12516             mFlags = flags;
12517             return super.queryIntent(intent, resolvedType,
12518                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12519                     userId);
12520         }
12521
12522         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12523                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12524             if (!sUserManager.exists(userId)) return null;
12525             if (packageServices == null) {
12526                 return null;
12527             }
12528             mFlags = flags;
12529             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12530             final int N = packageServices.size();
12531             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12532                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12533
12534             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12535             for (int i = 0; i < N; ++i) {
12536                 intentFilters = packageServices.get(i).intents;
12537                 if (intentFilters != null && intentFilters.size() > 0) {
12538                     PackageParser.ServiceIntentInfo[] array =
12539                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
12540                     intentFilters.toArray(array);
12541                     listCut.add(array);
12542                 }
12543             }
12544             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12545         }
12546
12547         public final void addService(PackageParser.Service s) {
12548             mServices.put(s.getComponentName(), s);
12549             if (DEBUG_SHOW_INFO) {
12550                 Log.v(TAG, "  "
12551                         + (s.info.nonLocalizedLabel != null
12552                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
12553                 Log.v(TAG, "    Class=" + s.info.name);
12554             }
12555             final int NI = s.intents.size();
12556             int j;
12557             for (j=0; j<NI; j++) {
12558                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12559                 if (DEBUG_SHOW_INFO) {
12560                     Log.v(TAG, "    IntentFilter:");
12561                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12562                 }
12563                 if (!intent.debugCheck()) {
12564                     Log.w(TAG, "==> For Service " + s.info.name);
12565                 }
12566                 addFilter(intent);
12567             }
12568         }
12569
12570         public final void removeService(PackageParser.Service s) {
12571             mServices.remove(s.getComponentName());
12572             if (DEBUG_SHOW_INFO) {
12573                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12574                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
12575                 Log.v(TAG, "    Class=" + s.info.name);
12576             }
12577             final int NI = s.intents.size();
12578             int j;
12579             for (j=0; j<NI; j++) {
12580                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12581                 if (DEBUG_SHOW_INFO) {
12582                     Log.v(TAG, "    IntentFilter:");
12583                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12584                 }
12585                 removeFilter(intent);
12586             }
12587         }
12588
12589         @Override
12590         protected boolean allowFilterResult(
12591                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12592             ServiceInfo filterSi = filter.service.info;
12593             for (int i=dest.size()-1; i>=0; i--) {
12594                 ServiceInfo destAi = dest.get(i).serviceInfo;
12595                 if (destAi.name == filterSi.name
12596                         && destAi.packageName == filterSi.packageName) {
12597                     return false;
12598                 }
12599             }
12600             return true;
12601         }
12602
12603         @Override
12604         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12605             return new PackageParser.ServiceIntentInfo[size];
12606         }
12607
12608         @Override
12609         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12610             if (!sUserManager.exists(userId)) return true;
12611             PackageParser.Package p = filter.service.owner;
12612             if (p != null) {
12613                 PackageSetting ps = (PackageSetting)p.mExtras;
12614                 if (ps != null) {
12615                     // System apps are never considered stopped for purposes of
12616                     // filtering, because there may be no way for the user to
12617                     // actually re-launch them.
12618                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12619                             && ps.getStopped(userId);
12620                 }
12621             }
12622             return false;
12623         }
12624
12625         @Override
12626         protected boolean isPackageForFilter(String packageName,
12627                 PackageParser.ServiceIntentInfo info) {
12628             return packageName.equals(info.service.owner.packageName);
12629         }
12630
12631         @Override
12632         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12633                 int match, int userId) {
12634             if (!sUserManager.exists(userId)) return null;
12635             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12636             if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12637                 return null;
12638             }
12639             final PackageParser.Service service = info.service;
12640             PackageSetting ps = (PackageSetting) service.owner.mExtras;
12641             if (ps == null) {
12642                 return null;
12643             }
12644             final PackageUserState userState = ps.readUserState(userId);
12645             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12646                     userState, userId);
12647             if (si == null) {
12648                 return null;
12649             }
12650             final boolean matchVisibleToInstantApp =
12651                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12652             final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12653             // throw out filters that aren't visible to ephemeral apps
12654             if (matchVisibleToInstantApp
12655                     && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12656                 return null;
12657             }
12658             // throw out ephemeral filters if we're not explicitly requesting them
12659             if (!isInstantApp && userState.instantApp) {
12660                 return null;
12661             }
12662             // throw out instant app filters if updates are available; will trigger
12663             // instant app resolution
12664             if (userState.instantApp && ps.isUpdateAvailable()) {
12665                 return null;
12666             }
12667             final ResolveInfo res = new ResolveInfo();
12668             res.serviceInfo = si;
12669             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12670                 res.filter = filter;
12671             }
12672             res.priority = info.getPriority();
12673             res.preferredOrder = service.owner.mPreferredOrder;
12674             res.match = match;
12675             res.isDefault = info.hasDefault;
12676             res.labelRes = info.labelRes;
12677             res.nonLocalizedLabel = info.nonLocalizedLabel;
12678             res.icon = info.icon;
12679             res.system = res.serviceInfo.applicationInfo.isSystemApp();
12680             return res;
12681         }
12682
12683         @Override
12684         protected void sortResults(List<ResolveInfo> results) {
12685             Collections.sort(results, mResolvePrioritySorter);
12686         }
12687
12688         @Override
12689         protected void dumpFilter(PrintWriter out, String prefix,
12690                 PackageParser.ServiceIntentInfo filter) {
12691             out.print(prefix); out.print(
12692                     Integer.toHexString(System.identityHashCode(filter.service)));
12693                     out.print(' ');
12694                     filter.service.printComponentShortName(out);
12695                     out.print(" filter ");
12696                     out.println(Integer.toHexString(System.identityHashCode(filter)));
12697         }
12698
12699         @Override
12700         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12701             return filter.service;
12702         }
12703
12704         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12705             PackageParser.Service service = (PackageParser.Service)label;
12706             out.print(prefix); out.print(
12707                     Integer.toHexString(System.identityHashCode(service)));
12708                     out.print(' ');
12709                     service.printComponentShortName(out);
12710             if (count > 1) {
12711                 out.print(" ("); out.print(count); out.print(" filters)");
12712             }
12713             out.println();
12714         }
12715
12716 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12717 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12718 //            final List<ResolveInfo> retList = Lists.newArrayList();
12719 //            while (i.hasNext()) {
12720 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
12721 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
12722 //                    retList.add(resolveInfo);
12723 //                }
12724 //            }
12725 //            return retList;
12726 //        }
12727
12728         // Keys are String (activity class name), values are Activity.
12729         private final ArrayMap<ComponentName, PackageParser.Service> mServices
12730                 = new ArrayMap<ComponentName, PackageParser.Service>();
12731         private int mFlags;
12732     }
12733
12734     private final class ProviderIntentResolver
12735             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12736         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12737                 boolean defaultOnly, int userId) {
12738             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12739             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12740         }
12741
12742         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12743                 int userId) {
12744             if (!sUserManager.exists(userId))
12745                 return null;
12746             mFlags = flags;
12747             return super.queryIntent(intent, resolvedType,
12748                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12749                     userId);
12750         }
12751
12752         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12753                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12754             if (!sUserManager.exists(userId))
12755                 return null;
12756             if (packageProviders == null) {
12757                 return null;
12758             }
12759             mFlags = flags;
12760             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12761             final int N = packageProviders.size();
12762             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12763                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12764
12765             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12766             for (int i = 0; i < N; ++i) {
12767                 intentFilters = packageProviders.get(i).intents;
12768                 if (intentFilters != null && intentFilters.size() > 0) {
12769                     PackageParser.ProviderIntentInfo[] array =
12770                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
12771                     intentFilters.toArray(array);
12772                     listCut.add(array);
12773                 }
12774             }
12775             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12776         }
12777
12778         public final void addProvider(PackageParser.Provider p) {
12779             if (mProviders.containsKey(p.getComponentName())) {
12780                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12781                 return;
12782             }
12783
12784             mProviders.put(p.getComponentName(), p);
12785             if (DEBUG_SHOW_INFO) {
12786                 Log.v(TAG, "  "
12787                         + (p.info.nonLocalizedLabel != null
12788                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
12789                 Log.v(TAG, "    Class=" + p.info.name);
12790             }
12791             final int NI = p.intents.size();
12792             int j;
12793             for (j = 0; j < NI; j++) {
12794                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12795                 if (DEBUG_SHOW_INFO) {
12796                     Log.v(TAG, "    IntentFilter:");
12797                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12798                 }
12799                 if (!intent.debugCheck()) {
12800                     Log.w(TAG, "==> For Provider " + p.info.name);
12801                 }
12802                 addFilter(intent);
12803             }
12804         }
12805
12806         public final void removeProvider(PackageParser.Provider p) {
12807             mProviders.remove(p.getComponentName());
12808             if (DEBUG_SHOW_INFO) {
12809                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12810                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
12811                 Log.v(TAG, "    Class=" + p.info.name);
12812             }
12813             final int NI = p.intents.size();
12814             int j;
12815             for (j = 0; j < NI; j++) {
12816                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12817                 if (DEBUG_SHOW_INFO) {
12818                     Log.v(TAG, "    IntentFilter:");
12819                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12820                 }
12821                 removeFilter(intent);
12822             }
12823         }
12824
12825         @Override
12826         protected boolean allowFilterResult(
12827                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12828             ProviderInfo filterPi = filter.provider.info;
12829             for (int i = dest.size() - 1; i >= 0; i--) {
12830                 ProviderInfo destPi = dest.get(i).providerInfo;
12831                 if (destPi.name == filterPi.name
12832                         && destPi.packageName == filterPi.packageName) {
12833                     return false;
12834                 }
12835             }
12836             return true;
12837         }
12838
12839         @Override
12840         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12841             return new PackageParser.ProviderIntentInfo[size];
12842         }
12843
12844         @Override
12845         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12846             if (!sUserManager.exists(userId))
12847                 return true;
12848             PackageParser.Package p = filter.provider.owner;
12849             if (p != null) {
12850                 PackageSetting ps = (PackageSetting) p.mExtras;
12851                 if (ps != null) {
12852                     // System apps are never considered stopped for purposes of
12853                     // filtering, because there may be no way for the user to
12854                     // actually re-launch them.
12855                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12856                             && ps.getStopped(userId);
12857                 }
12858             }
12859             return false;
12860         }
12861
12862         @Override
12863         protected boolean isPackageForFilter(String packageName,
12864                 PackageParser.ProviderIntentInfo info) {
12865             return packageName.equals(info.provider.owner.packageName);
12866         }
12867
12868         @Override
12869         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12870                 int match, int userId) {
12871             if (!sUserManager.exists(userId))
12872                 return null;
12873             final PackageParser.ProviderIntentInfo info = filter;
12874             if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12875                 return null;
12876             }
12877             final PackageParser.Provider provider = info.provider;
12878             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12879             if (ps == null) {
12880                 return null;
12881             }
12882             final PackageUserState userState = ps.readUserState(userId);
12883             final boolean matchVisibleToInstantApp =
12884                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12885             final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12886             // throw out filters that aren't visible to instant applications
12887             if (matchVisibleToInstantApp
12888                     && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12889                 return null;
12890             }
12891             // throw out instant application filters if we're not explicitly requesting them
12892             if (!isInstantApp && userState.instantApp) {
12893                 return null;
12894             }
12895             // throw out instant application filters if updates are available; will trigger
12896             // instant application resolution
12897             if (userState.instantApp && ps.isUpdateAvailable()) {
12898                 return null;
12899             }
12900             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12901                     userState, userId);
12902             if (pi == null) {
12903                 return null;
12904             }
12905             final ResolveInfo res = new ResolveInfo();
12906             res.providerInfo = pi;
12907             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12908                 res.filter = filter;
12909             }
12910             res.priority = info.getPriority();
12911             res.preferredOrder = provider.owner.mPreferredOrder;
12912             res.match = match;
12913             res.isDefault = info.hasDefault;
12914             res.labelRes = info.labelRes;
12915             res.nonLocalizedLabel = info.nonLocalizedLabel;
12916             res.icon = info.icon;
12917             res.system = res.providerInfo.applicationInfo.isSystemApp();
12918             return res;
12919         }
12920
12921         @Override
12922         protected void sortResults(List<ResolveInfo> results) {
12923             Collections.sort(results, mResolvePrioritySorter);
12924         }
12925
12926         @Override
12927         protected void dumpFilter(PrintWriter out, String prefix,
12928                 PackageParser.ProviderIntentInfo filter) {
12929             out.print(prefix);
12930             out.print(
12931                     Integer.toHexString(System.identityHashCode(filter.provider)));
12932             out.print(' ');
12933             filter.provider.printComponentShortName(out);
12934             out.print(" filter ");
12935             out.println(Integer.toHexString(System.identityHashCode(filter)));
12936         }
12937
12938         @Override
12939         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12940             return filter.provider;
12941         }
12942
12943         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12944             PackageParser.Provider provider = (PackageParser.Provider)label;
12945             out.print(prefix); out.print(
12946                     Integer.toHexString(System.identityHashCode(provider)));
12947                     out.print(' ');
12948                     provider.printComponentShortName(out);
12949             if (count > 1) {
12950                 out.print(" ("); out.print(count); out.print(" filters)");
12951             }
12952             out.println();
12953         }
12954
12955         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12956                 = new ArrayMap<ComponentName, PackageParser.Provider>();
12957         private int mFlags;
12958     }
12959
12960     static final class EphemeralIntentResolver
12961             extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12962         /**
12963          * The result that has the highest defined order. Ordering applies on a
12964          * per-package basis. Mapping is from package name to Pair of order and
12965          * EphemeralResolveInfo.
12966          * <p>
12967          * NOTE: This is implemented as a field variable for convenience and efficiency.
12968          * By having a field variable, we're able to track filter ordering as soon as
12969          * a non-zero order is defined. Otherwise, multiple loops across the result set
12970          * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12971          * this needs to be contained entirely within {@link #filterResults}.
12972          */
12973         final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12974
12975         @Override
12976         protected AuxiliaryResolveInfo[] newArray(int size) {
12977             return new AuxiliaryResolveInfo[size];
12978         }
12979
12980         @Override
12981         protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12982             return true;
12983         }
12984
12985         @Override
12986         protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12987                 int userId) {
12988             if (!sUserManager.exists(userId)) {
12989                 return null;
12990             }
12991             final String packageName = responseObj.resolveInfo.getPackageName();
12992             final Integer order = responseObj.getOrder();
12993             final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12994                     mOrderResult.get(packageName);
12995             // ordering is enabled and this item's order isn't high enough
12996             if (lastOrderResult != null && lastOrderResult.first >= order) {
12997                 return null;
12998             }
12999             final InstantAppResolveInfo res = responseObj.resolveInfo;
13000             if (order > 0) {
13001                 // non-zero order, enable ordering
13002                 mOrderResult.put(packageName, new Pair<>(order, res));
13003             }
13004             return responseObj;
13005         }
13006
13007         @Override
13008         protected void filterResults(List<AuxiliaryResolveInfo> results) {
13009             // only do work if ordering is enabled [most of the time it won't be]
13010             if (mOrderResult.size() == 0) {
13011                 return;
13012             }
13013             int resultSize = results.size();
13014             for (int i = 0; i < resultSize; i++) {
13015                 final InstantAppResolveInfo info = results.get(i).resolveInfo;
13016                 final String packageName = info.getPackageName();
13017                 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13018                 if (savedInfo == null) {
13019                     // package doesn't having ordering
13020                     continue;
13021                 }
13022                 if (savedInfo.second == info) {
13023                     // circled back to the highest ordered item; remove from order list
13024                     mOrderResult.remove(savedInfo);
13025                     if (mOrderResult.size() == 0) {
13026                         // no more ordered items
13027                         break;
13028                     }
13029                     continue;
13030                 }
13031                 // item has a worse order, remove it from the result list
13032                 results.remove(i);
13033                 resultSize--;
13034                 i--;
13035             }
13036         }
13037     }
13038
13039     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13040             new Comparator<ResolveInfo>() {
13041         public int compare(ResolveInfo r1, ResolveInfo r2) {
13042             int v1 = r1.priority;
13043             int v2 = r2.priority;
13044             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13045             if (v1 != v2) {
13046                 return (v1 > v2) ? -1 : 1;
13047             }
13048             v1 = r1.preferredOrder;
13049             v2 = r2.preferredOrder;
13050             if (v1 != v2) {
13051                 return (v1 > v2) ? -1 : 1;
13052             }
13053             if (r1.isDefault != r2.isDefault) {
13054                 return r1.isDefault ? -1 : 1;
13055             }
13056             v1 = r1.match;
13057             v2 = r2.match;
13058             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13059             if (v1 != v2) {
13060                 return (v1 > v2) ? -1 : 1;
13061             }
13062             if (r1.system != r2.system) {
13063                 return r1.system ? -1 : 1;
13064             }
13065             if (r1.activityInfo != null) {
13066                 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13067             }
13068             if (r1.serviceInfo != null) {
13069                 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13070             }
13071             if (r1.providerInfo != null) {
13072                 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13073             }
13074             return 0;
13075         }
13076     };
13077
13078     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13079             new Comparator<ProviderInfo>() {
13080         public int compare(ProviderInfo p1, ProviderInfo p2) {
13081             final int v1 = p1.initOrder;
13082             final int v2 = p2.initOrder;
13083             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13084         }
13085     };
13086
13087     public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13088             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13089             final int[] userIds) {
13090         mHandler.post(new Runnable() {
13091             @Override
13092             public void run() {
13093                 try {
13094                     final IActivityManager am = ActivityManager.getService();
13095                     if (am == null) return;
13096                     final int[] resolvedUserIds;
13097                     if (userIds == null) {
13098                         resolvedUserIds = am.getRunningUserIds();
13099                     } else {
13100                         resolvedUserIds = userIds;
13101                     }
13102                     for (int id : resolvedUserIds) {
13103                         final Intent intent = new Intent(action,
13104                                 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13105                         if (extras != null) {
13106                             intent.putExtras(extras);
13107                         }
13108                         if (targetPkg != null) {
13109                             intent.setPackage(targetPkg);
13110                         }
13111                         // Modify the UID when posting to other users
13112                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13113                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
13114                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13115                             intent.putExtra(Intent.EXTRA_UID, uid);
13116                         }
13117                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13118                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13119                         if (DEBUG_BROADCASTS) {
13120                             RuntimeException here = new RuntimeException("here");
13121                             here.fillInStackTrace();
13122                             Slog.d(TAG, "Sending to user " + id + ": "
13123                                     + intent.toShortString(false, true, false, false)
13124                                     + " " + intent.getExtras(), here);
13125                         }
13126                         am.broadcastIntent(null, intent, null, finishedReceiver,
13127                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
13128                                 null, finishedReceiver != null, false, id);
13129                     }
13130                 } catch (RemoteException ex) {
13131                 }
13132             }
13133         });
13134     }
13135
13136     /**
13137      * Check if the external storage media is available. This is true if there
13138      * is a mounted external storage medium or if the external storage is
13139      * emulated.
13140      */
13141     private boolean isExternalMediaAvailable() {
13142         return mMediaMounted || Environment.isExternalStorageEmulated();
13143     }
13144
13145     @Override
13146     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13147         // writer
13148         synchronized (mPackages) {
13149             if (!isExternalMediaAvailable()) {
13150                 // If the external storage is no longer mounted at this point,
13151                 // the caller may not have been able to delete all of this
13152                 // packages files and can not delete any more.  Bail.
13153                 return null;
13154             }
13155             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13156             if (lastPackage != null) {
13157                 pkgs.remove(lastPackage);
13158             }
13159             if (pkgs.size() > 0) {
13160                 return pkgs.get(0);
13161             }
13162         }
13163         return null;
13164     }
13165
13166     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13167         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13168                 userId, andCode ? 1 : 0, packageName);
13169         if (mSystemReady) {
13170             msg.sendToTarget();
13171         } else {
13172             if (mPostSystemReadyMessages == null) {
13173                 mPostSystemReadyMessages = new ArrayList<>();
13174             }
13175             mPostSystemReadyMessages.add(msg);
13176         }
13177     }
13178
13179     void startCleaningPackages() {
13180         // reader
13181         if (!isExternalMediaAvailable()) {
13182             return;
13183         }
13184         synchronized (mPackages) {
13185             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13186                 return;
13187             }
13188         }
13189         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13190         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13191         IActivityManager am = ActivityManager.getService();
13192         if (am != null) {
13193             int dcsUid = -1;
13194             synchronized (mPackages) {
13195                 if (!mDefaultContainerWhitelisted) {
13196                     mDefaultContainerWhitelisted = true;
13197                     PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13198                     dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13199                 }
13200             }
13201             try {
13202                 if (dcsUid > 0) {
13203                     am.backgroundWhitelistUid(dcsUid);
13204                 }
13205                 am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
13206                         UserHandle.USER_SYSTEM);
13207             } catch (RemoteException e) {
13208             }
13209         }
13210     }
13211
13212     @Override
13213     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13214             int installFlags, String installerPackageName, int userId) {
13215         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13216
13217         final int callingUid = Binder.getCallingUid();
13218         enforceCrossUserPermission(callingUid, userId,
13219                 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13220
13221         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13222             try {
13223                 if (observer != null) {
13224                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13225                 }
13226             } catch (RemoteException re) {
13227             }
13228             return;
13229         }
13230
13231         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13232             installFlags |= PackageManager.INSTALL_FROM_ADB;
13233
13234         } else {
13235             // Caller holds INSTALL_PACKAGES permission, so we're less strict
13236             // about installerPackageName.
13237
13238             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13239             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13240         }
13241
13242         UserHandle user;
13243         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13244             user = UserHandle.ALL;
13245         } else {
13246             user = new UserHandle(userId);
13247         }
13248
13249         // Only system components can circumvent runtime permissions when installing.
13250         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13251                 && mContext.checkCallingOrSelfPermission(Manifest.permission
13252                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13253             throw new SecurityException("You need the "
13254                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13255                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13256         }
13257
13258         if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13259                 || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13260             throw new IllegalArgumentException(
13261                     "New installs into ASEC containers no longer supported");
13262         }
13263
13264         final File originFile = new File(originPath);
13265         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13266
13267         final Message msg = mHandler.obtainMessage(INIT_COPY);
13268         final VerificationInfo verificationInfo = new VerificationInfo(
13269                 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13270         final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13271                 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13272                 null /*packageAbiOverride*/, null /*grantedPermissions*/,
13273                 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13274         params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13275         msg.obj = params;
13276
13277         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13278                 System.identityHashCode(msg.obj));
13279         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13280                 System.identityHashCode(msg.obj));
13281
13282         mHandler.sendMessage(msg);
13283     }
13284
13285
13286     /**
13287      * Ensure that the install reason matches what we know about the package installer (e.g. whether
13288      * it is acting on behalf on an enterprise or the user).
13289      *
13290      * Note that the ordering of the conditionals in this method is important. The checks we perform
13291      * are as follows, in this order:
13292      *
13293      * 1) If the install is being performed by a system app, we can trust the app to have set the
13294      *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13295      *    what it is.
13296      * 2) If the install is being performed by a device or profile owner app, the install reason
13297      *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13298      *    set the install reason correctly. If the app targets an older SDK version where install
13299      *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13300      *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13301      * 3) In all other cases, the install is being performed by a regular app that is neither part
13302      *    of the system nor a device or profile owner. We have no reason to believe that this app is
13303      *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13304      *    set to enterprise policy and if so, change it to unknown instead.
13305      */
13306     private int fixUpInstallReason(String installerPackageName, int installerUid,
13307             int installReason) {
13308         if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13309                 == PERMISSION_GRANTED) {
13310             // If the install is being performed by a system app, we trust that app to have set the
13311             // install reason correctly.
13312             return installReason;
13313         }
13314
13315         final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13316             ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13317         if (dpm != null) {
13318             ComponentName owner = null;
13319             try {
13320                 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13321                 if (owner == null) {
13322                     owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13323                 }
13324             } catch (RemoteException e) {
13325             }
13326             if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13327                 // If the install is being performed by a device or profile owner, the install
13328                 // reason should be enterprise policy.
13329                 return PackageManager.INSTALL_REASON_POLICY;
13330             }
13331         }
13332
13333         if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13334             // If the install is being performed by a regular app (i.e. neither system app nor
13335             // device or profile owner), we have no reason to believe that the app is acting on
13336             // behalf of an enterprise. If the app set the install reason to enterprise policy,
13337             // change it to unknown instead.
13338             return PackageManager.INSTALL_REASON_UNKNOWN;
13339         }
13340
13341         // If the install is being performed by a regular app and the install reason was set to any
13342         // value but enterprise policy, leave the install reason unchanged.
13343         return installReason;
13344     }
13345
13346     void installStage(String packageName, File stagedDir, String stagedCid,
13347             IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13348             String installerPackageName, int installerUid, UserHandle user,
13349             Certificate[][] certificates) {
13350         if (DEBUG_EPHEMERAL) {
13351             if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13352                 Slog.d(TAG, "Ephemeral install of " + packageName);
13353             }
13354         }
13355         final VerificationInfo verificationInfo = new VerificationInfo(
13356                 sessionParams.originatingUri, sessionParams.referrerUri,
13357                 sessionParams.originatingUid, installerUid);
13358
13359         final OriginInfo origin;
13360         if (stagedDir != null) {
13361             origin = OriginInfo.fromStagedFile(stagedDir);
13362         } else {
13363             origin = OriginInfo.fromStagedContainer(stagedCid);
13364         }
13365
13366         final Message msg = mHandler.obtainMessage(INIT_COPY);
13367         final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13368                 sessionParams.installReason);
13369         final InstallParams params = new InstallParams(origin, null, observer,
13370                 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13371                 verificationInfo, user, sessionParams.abiOverride,
13372                 sessionParams.grantedRuntimePermissions, certificates, installReason);
13373         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13374         msg.obj = params;
13375
13376         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13377                 System.identityHashCode(msg.obj));
13378         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13379                 System.identityHashCode(msg.obj));
13380
13381         mHandler.sendMessage(msg);
13382     }
13383
13384     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13385             int userId) {
13386         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13387         sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13388     }
13389
13390     public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
13391         if (ArrayUtils.isEmpty(userIds)) {
13392             return;
13393         }
13394         Bundle extras = new Bundle(1);
13395         // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13396         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13397
13398         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
13399                 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, userIds);
13400         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13401                 extras, 0, null, null, userIds);
13402         if (isSystem) {
13403             mHandler.post(() -> {
13404                         for (int userId : userIds) {
13405                             sendBootCompletedBroadcastToSystemApp(packageName, userId);
13406                         }
13407                     }
13408             );
13409         }
13410     }
13411
13412     /**
13413      * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13414      * automatically without needing an explicit launch.
13415      * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13416      */
13417     private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13418         // If user is not running, the app didn't miss any broadcast
13419         if (!mUserManagerInternal.isUserRunning(userId)) {
13420             return;
13421         }
13422         final IActivityManager am = ActivityManager.getService();
13423         try {
13424             // Deliver LOCKED_BOOT_COMPLETED first
13425             Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13426                     .setPackage(packageName);
13427             final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13428             am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13429                     android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13430
13431             // Deliver BOOT_COMPLETED only if user is unlocked
13432             if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13433                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13434                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13435                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13436             }
13437         } catch (RemoteException e) {
13438             throw e.rethrowFromSystemServer();
13439         }
13440     }
13441
13442     @Override
13443     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13444             int userId) {
13445         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13446         PackageSetting pkgSetting;
13447         final int uid = Binder.getCallingUid();
13448         enforceCrossUserPermission(uid, userId,
13449                 true /* requireFullPermission */, true /* checkShell */,
13450                 "setApplicationHiddenSetting for user " + userId);
13451
13452         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13453             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13454             return false;
13455         }
13456
13457         long callingId = Binder.clearCallingIdentity();
13458         try {
13459             boolean sendAdded = false;
13460             boolean sendRemoved = false;
13461             // writer
13462             synchronized (mPackages) {
13463                 pkgSetting = mSettings.mPackages.get(packageName);
13464                 if (pkgSetting == null) {
13465                     return false;
13466                 }
13467                 // Do not allow "android" is being disabled
13468                 if ("android".equals(packageName)) {
13469                     Slog.w(TAG, "Cannot hide package: android");
13470                     return false;
13471                 }
13472                 // Cannot hide static shared libs as they are considered
13473                 // a part of the using app (emulating static linking). Also
13474                 // static libs are installed always on internal storage.
13475                 PackageParser.Package pkg = mPackages.get(packageName);
13476                 if (pkg != null && pkg.staticSharedLibName != null) {
13477                     Slog.w(TAG, "Cannot hide package: " + packageName
13478                             + " providing static shared library: "
13479                             + pkg.staticSharedLibName);
13480                     return false;
13481                 }
13482                 // Only allow protected packages to hide themselves.
13483                 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13484                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13485                     Slog.w(TAG, "Not hiding protected package: " + packageName);
13486                     return false;
13487                 }
13488
13489                 if (pkgSetting.getHidden(userId) != hidden) {
13490                     pkgSetting.setHidden(hidden, userId);
13491                     mSettings.writePackageRestrictionsLPr(userId);
13492                     if (hidden) {
13493                         sendRemoved = true;
13494                     } else {
13495                         sendAdded = true;
13496                     }
13497                 }
13498             }
13499             if (sendAdded) {
13500                 sendPackageAddedForUser(packageName, pkgSetting, userId);
13501                 return true;
13502             }
13503             if (sendRemoved) {
13504                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13505                         "hiding pkg");
13506                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13507                 return true;
13508             }
13509         } finally {
13510             Binder.restoreCallingIdentity(callingId);
13511         }
13512         return false;
13513     }
13514
13515     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13516             int userId) {
13517         final PackageRemovedInfo info = new PackageRemovedInfo(this);
13518         info.removedPackage = packageName;
13519         info.removedUsers = new int[] {userId};
13520         info.broadcastUsers = new int[] {userId};
13521         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13522         info.sendPackageRemovedBroadcasts(true /*killApp*/);
13523     }
13524
13525     private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13526         if (pkgList.length > 0) {
13527             Bundle extras = new Bundle(1);
13528             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13529
13530             sendPackageBroadcast(
13531                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13532                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
13533                     null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13534                     new int[] {userId});
13535         }
13536     }
13537
13538     /**
13539      * Returns true if application is not found or there was an error. Otherwise it returns
13540      * the hidden state of the package for the given user.
13541      */
13542     @Override
13543     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13544         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13545         enforceCrossUserPermission(Binder.getCallingUid(), userId,
13546                 true /* requireFullPermission */, false /* checkShell */,
13547                 "getApplicationHidden for user " + userId);
13548         PackageSetting pkgSetting;
13549         long callingId = Binder.clearCallingIdentity();
13550         try {
13551             // writer
13552             synchronized (mPackages) {
13553                 pkgSetting = mSettings.mPackages.get(packageName);
13554                 if (pkgSetting == null) {
13555                     return true;
13556                 }
13557                 return pkgSetting.getHidden(userId);
13558             }
13559         } finally {
13560             Binder.restoreCallingIdentity(callingId);
13561         }
13562     }
13563
13564     /**
13565      * @hide
13566      */
13567     @Override
13568     public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13569             int installReason) {
13570         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13571                 null);
13572         PackageSetting pkgSetting;
13573         final int uid = Binder.getCallingUid();
13574         enforceCrossUserPermission(uid, userId,
13575                 true /* requireFullPermission */, true /* checkShell */,
13576                 "installExistingPackage for user " + userId);
13577         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13578             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13579         }
13580
13581         long callingId = Binder.clearCallingIdentity();
13582         try {
13583             boolean installed = false;
13584             final boolean instantApp =
13585                     (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13586             final boolean fullApp =
13587                     (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13588
13589             // writer
13590             synchronized (mPackages) {
13591                 pkgSetting = mSettings.mPackages.get(packageName);
13592                 if (pkgSetting == null) {
13593                     return PackageManager.INSTALL_FAILED_INVALID_URI;
13594                 }
13595                 if (!pkgSetting.getInstalled(userId)) {
13596                     pkgSetting.setInstalled(true, userId);
13597                     pkgSetting.setHidden(false, userId);
13598                     pkgSetting.setInstallReason(installReason, userId);
13599                     mSettings.writePackageRestrictionsLPr(userId);
13600                     mSettings.writeKernelMappingLPr(pkgSetting);
13601                     installed = true;
13602                 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13603                     // upgrade app from instant to full; we don't allow app downgrade
13604                     installed = true;
13605                 }
13606                 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13607             }
13608
13609             if (installed) {
13610                 if (pkgSetting.pkg != null) {
13611                     synchronized (mInstallLock) {
13612                         // We don't need to freeze for a brand new install
13613                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13614                     }
13615                 }
13616                 sendPackageAddedForUser(packageName, pkgSetting, userId);
13617                 synchronized (mPackages) {
13618                     updateSequenceNumberLP(packageName, new int[]{ userId });
13619                 }
13620             }
13621         } finally {
13622             Binder.restoreCallingIdentity(callingId);
13623         }
13624
13625         return PackageManager.INSTALL_SUCCEEDED;
13626     }
13627
13628     void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13629             boolean instantApp, boolean fullApp) {
13630         // no state specified; do nothing
13631         if (!instantApp && !fullApp) {
13632             return;
13633         }
13634         if (userId != UserHandle.USER_ALL) {
13635             if (instantApp && !pkgSetting.getInstantApp(userId)) {
13636                 pkgSetting.setInstantApp(true /*instantApp*/, userId);
13637             } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13638                 pkgSetting.setInstantApp(false /*instantApp*/, userId);
13639             }
13640         } else {
13641             for (int currentUserId : sUserManager.getUserIds()) {
13642                 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13643                     pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13644                 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13645                     pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13646                 }
13647             }
13648         }
13649     }
13650
13651     boolean isUserRestricted(int userId, String restrictionKey) {
13652         Bundle restrictions = sUserManager.getUserRestrictions(userId);
13653         if (restrictions.getBoolean(restrictionKey, false)) {
13654             Log.w(TAG, "User is restricted: " + restrictionKey);
13655             return true;
13656         }
13657         return false;
13658     }
13659
13660     @Override
13661     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13662             int userId) {
13663         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13664         enforceCrossUserPermission(Binder.getCallingUid(), userId,
13665                 true /* requireFullPermission */, true /* checkShell */,
13666                 "setPackagesSuspended for user " + userId);
13667
13668         if (ArrayUtils.isEmpty(packageNames)) {
13669             return packageNames;
13670         }
13671
13672         // List of package names for whom the suspended state has changed.
13673         List<String> changedPackages = new ArrayList<>(packageNames.length);
13674         // List of package names for whom the suspended state is not set as requested in this
13675         // method.
13676         List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13677         long callingId = Binder.clearCallingIdentity();
13678         try {
13679             for (int i = 0; i < packageNames.length; i++) {
13680                 String packageName = packageNames[i];
13681                 boolean changed = false;
13682                 final int appId;
13683                 synchronized (mPackages) {
13684                     final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13685                     if (pkgSetting == null) {
13686                         Slog.w(TAG, "Could not find package setting for package \"" + packageName
13687                                 + "\". Skipping suspending/un-suspending.");
13688                         unactionedPackages.add(packageName);
13689                         continue;
13690                     }
13691                     appId = pkgSetting.appId;
13692                     if (pkgSetting.getSuspended(userId) != suspended) {
13693                         if (!canSuspendPackageForUserLocked(packageName, userId)) {
13694                             unactionedPackages.add(packageName);
13695                             continue;
13696                         }
13697                         pkgSetting.setSuspended(suspended, userId);
13698                         mSettings.writePackageRestrictionsLPr(userId);
13699                         changed = true;
13700                         changedPackages.add(packageName);
13701                     }
13702                 }
13703
13704                 if (changed && suspended) {
13705                     killApplication(packageName, UserHandle.getUid(userId, appId),
13706                             "suspending package");
13707                 }
13708             }
13709         } finally {
13710             Binder.restoreCallingIdentity(callingId);
13711         }
13712
13713         if (!changedPackages.isEmpty()) {
13714             sendPackagesSuspendedForUser(changedPackages.toArray(
13715                     new String[changedPackages.size()]), userId, suspended);
13716         }
13717
13718         return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13719     }
13720
13721     @Override
13722     public boolean isPackageSuspendedForUser(String packageName, int userId) {
13723         enforceCrossUserPermission(Binder.getCallingUid(), userId,
13724                 true /* requireFullPermission */, false /* checkShell */,
13725                 "isPackageSuspendedForUser for user " + userId);
13726         synchronized (mPackages) {
13727             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13728             if (pkgSetting == null) {
13729                 throw new IllegalArgumentException("Unknown target package: " + packageName);
13730             }
13731             return pkgSetting.getSuspended(userId);
13732         }
13733     }
13734
13735     private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13736         if (isPackageDeviceAdmin(packageName, userId)) {
13737             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13738                     + "\": has an active device admin");
13739             return false;
13740         }
13741
13742         String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13743         if (packageName.equals(activeLauncherPackageName)) {
13744             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13745                     + "\": contains the active launcher");
13746             return false;
13747         }
13748
13749         if (packageName.equals(mRequiredInstallerPackage)) {
13750             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13751                     + "\": required for package installation");
13752             return false;
13753         }
13754
13755         if (packageName.equals(mRequiredUninstallerPackage)) {
13756             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13757                     + "\": required for package uninstallation");
13758             return false;
13759         }
13760
13761         if (packageName.equals(mRequiredVerifierPackage)) {
13762             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13763                     + "\": required for package verification");
13764             return false;
13765         }
13766
13767         if (packageName.equals(getDefaultDialerPackageName(userId))) {
13768             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13769                     + "\": is the default dialer");
13770             return false;
13771         }
13772
13773         if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13774             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13775                     + "\": protected package");
13776             return false;
13777         }
13778
13779         // Cannot suspend static shared libs as they are considered
13780         // a part of the using app (emulating static linking). Also
13781         // static libs are installed always on internal storage.
13782         PackageParser.Package pkg = mPackages.get(packageName);
13783         if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13784             Slog.w(TAG, "Cannot suspend package: " + packageName
13785                     + " providing static shared library: "
13786                     + pkg.staticSharedLibName);
13787             return false;
13788         }
13789
13790         return true;
13791     }
13792
13793     private String getActiveLauncherPackageName(int userId) {
13794         Intent intent = new Intent(Intent.ACTION_MAIN);
13795         intent.addCategory(Intent.CATEGORY_HOME);
13796         ResolveInfo resolveInfo = resolveIntent(
13797                 intent,
13798                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13799                 PackageManager.MATCH_DEFAULT_ONLY,
13800                 userId);
13801
13802         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13803     }
13804
13805     private String getDefaultDialerPackageName(int userId) {
13806         synchronized (mPackages) {
13807             return mSettings.getDefaultDialerPackageNameLPw(userId);
13808         }
13809     }
13810
13811     @Override
13812     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13813         mContext.enforceCallingOrSelfPermission(
13814                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13815                 "Only package verification agents can verify applications");
13816
13817         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13818         final PackageVerificationResponse response = new PackageVerificationResponse(
13819                 verificationCode, Binder.getCallingUid());
13820         msg.arg1 = id;
13821         msg.obj = response;
13822         mHandler.sendMessage(msg);
13823     }
13824
13825     @Override
13826     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13827             long millisecondsToDelay) {
13828         mContext.enforceCallingOrSelfPermission(
13829                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13830                 "Only package verification agents can extend verification timeouts");
13831
13832         final PackageVerificationState state = mPendingVerification.get(id);
13833         final PackageVerificationResponse response = new PackageVerificationResponse(
13834                 verificationCodeAtTimeout, Binder.getCallingUid());
13835
13836         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13837             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13838         }
13839         if (millisecondsToDelay < 0) {
13840             millisecondsToDelay = 0;
13841         }
13842         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13843                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13844             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13845         }
13846
13847         if ((state != null) && !state.timeoutExtended()) {
13848             state.extendTimeout();
13849
13850             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13851             msg.arg1 = id;
13852             msg.obj = response;
13853             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13854         }
13855     }
13856
13857     private void broadcastPackageVerified(int verificationId, Uri packageUri,
13858             int verificationCode, UserHandle user) {
13859         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13860         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13861         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13862         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13863         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13864
13865         mContext.sendBroadcastAsUser(intent, user,
13866                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13867     }
13868
13869     private ComponentName matchComponentForVerifier(String packageName,
13870             List<ResolveInfo> receivers) {
13871         ActivityInfo targetReceiver = null;
13872
13873         final int NR = receivers.size();
13874         for (int i = 0; i < NR; i++) {
13875             final ResolveInfo info = receivers.get(i);
13876             if (info.activityInfo == null) {
13877                 continue;
13878             }
13879
13880             if (packageName.equals(info.activityInfo.packageName)) {
13881                 targetReceiver = info.activityInfo;
13882                 break;
13883             }
13884         }
13885
13886         if (targetReceiver == null) {
13887             return null;
13888         }
13889
13890         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13891     }
13892
13893     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13894             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13895         if (pkgInfo.verifiers.length == 0) {
13896             return null;
13897         }
13898
13899         final int N = pkgInfo.verifiers.length;
13900         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13901         for (int i = 0; i < N; i++) {
13902             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13903
13904             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13905                     receivers);
13906             if (comp == null) {
13907                 continue;
13908             }
13909
13910             final int verifierUid = getUidForVerifier(verifierInfo);
13911             if (verifierUid == -1) {
13912                 continue;
13913             }
13914
13915             if (DEBUG_VERIFY) {
13916                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13917                         + " with the correct signature");
13918             }
13919             sufficientVerifiers.add(comp);
13920             verificationState.addSufficientVerifier(verifierUid);
13921         }
13922
13923         return sufficientVerifiers;
13924     }
13925
13926     private int getUidForVerifier(VerifierInfo verifierInfo) {
13927         synchronized (mPackages) {
13928             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13929             if (pkg == null) {
13930                 return -1;
13931             } else if (pkg.mSignatures.length != 1) {
13932                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13933                         + " has more than one signature; ignoring");
13934                 return -1;
13935             }
13936
13937             /*
13938              * If the public key of the package's signature does not match
13939              * our expected public key, then this is a different package and
13940              * we should skip.
13941              */
13942
13943             final byte[] expectedPublicKey;
13944             try {
13945                 final Signature verifierSig = pkg.mSignatures[0];
13946                 final PublicKey publicKey = verifierSig.getPublicKey();
13947                 expectedPublicKey = publicKey.getEncoded();
13948             } catch (CertificateException e) {
13949                 return -1;
13950             }
13951
13952             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13953
13954             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13955                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13956                         + " does not have the expected public key; ignoring");
13957                 return -1;
13958             }
13959
13960             return pkg.applicationInfo.uid;
13961         }
13962     }
13963
13964     @Override
13965     public void finishPackageInstall(int token, boolean didLaunch) {
13966         enforceSystemOrRoot("Only the system is allowed to finish installs");
13967
13968         if (DEBUG_INSTALL) {
13969             Slog.v(TAG, "BM finishing package install for " + token);
13970         }
13971         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13972
13973         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13974         mHandler.sendMessage(msg);
13975     }
13976
13977     /**
13978      * Get the verification agent timeout.
13979      *
13980      * @return verification timeout in milliseconds
13981      */
13982     private long getVerificationTimeout() {
13983         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13984                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13985                 DEFAULT_VERIFICATION_TIMEOUT);
13986     }
13987
13988     /**
13989      * Get the default verification agent response code.
13990      *
13991      * @return default verification response code
13992      */
13993     private int getDefaultVerificationResponse() {
13994         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13995                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13996                 DEFAULT_VERIFICATION_RESPONSE);
13997     }
13998
13999     /**
14000      * Check whether or not package verification has been enabled.
14001      *
14002      * @return true if verification should be performed
14003      */
14004     private boolean isVerificationEnabled(int userId, int installFlags) {
14005         if (!DEFAULT_VERIFY_ENABLE) {
14006             return false;
14007         }
14008
14009         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14010
14011         // Check if installing from ADB
14012         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14013             // Do not run verification in a test harness environment
14014             if (ActivityManager.isRunningInTestHarness()) {
14015                 return false;
14016             }
14017             if (ensureVerifyAppsEnabled) {
14018                 return true;
14019             }
14020             // Check if the developer does not want package verification for ADB installs
14021             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14022                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14023                 return false;
14024             }
14025         }
14026
14027         if (ensureVerifyAppsEnabled) {
14028             return true;
14029         }
14030
14031         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14032                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14033     }
14034
14035     @Override
14036     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14037             throws RemoteException {
14038         mContext.enforceCallingOrSelfPermission(
14039                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14040                 "Only intentfilter verification agents can verify applications");
14041
14042         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14043         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14044                 Binder.getCallingUid(), verificationCode, failedDomains);
14045         msg.arg1 = id;
14046         msg.obj = response;
14047         mHandler.sendMessage(msg);
14048     }
14049
14050     @Override
14051     public int getIntentVerificationStatus(String packageName, int userId) {
14052         synchronized (mPackages) {
14053             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14054         }
14055     }
14056
14057     @Override
14058     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14059         mContext.enforceCallingOrSelfPermission(
14060                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14061
14062         boolean result = false;
14063         synchronized (mPackages) {
14064             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14065         }
14066         if (result) {
14067             scheduleWritePackageRestrictionsLocked(userId);
14068         }
14069         return result;
14070     }
14071
14072     @Override
14073     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14074             String packageName) {
14075         synchronized (mPackages) {
14076             return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14077         }
14078     }
14079
14080     @Override
14081     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14082         if (TextUtils.isEmpty(packageName)) {
14083             return ParceledListSlice.emptyList();
14084         }
14085         synchronized (mPackages) {
14086             PackageParser.Package pkg = mPackages.get(packageName);
14087             if (pkg == null || pkg.activities == null) {
14088                 return ParceledListSlice.emptyList();
14089             }
14090             final int count = pkg.activities.size();
14091             ArrayList<IntentFilter> result = new ArrayList<>();
14092             for (int n=0; n<count; n++) {
14093                 PackageParser.Activity activity = pkg.activities.get(n);
14094                 if (activity.intents != null && activity.intents.size() > 0) {
14095                     result.addAll(activity.intents);
14096                 }
14097             }
14098             return new ParceledListSlice<>(result);
14099         }
14100     }
14101
14102     @Override
14103     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14104         mContext.enforceCallingOrSelfPermission(
14105                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14106
14107         synchronized (mPackages) {
14108             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14109             if (packageName != null) {
14110                 result |= updateIntentVerificationStatus(packageName,
14111                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
14112                         userId);
14113                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14114                         packageName, userId);
14115             }
14116             return result;
14117         }
14118     }
14119
14120     @Override
14121     public String getDefaultBrowserPackageName(int userId) {
14122         synchronized (mPackages) {
14123             return mSettings.getDefaultBrowserPackageNameLPw(userId);
14124         }
14125     }
14126
14127     /**
14128      * Get the "allow unknown sources" setting.
14129      *
14130      * @return the current "allow unknown sources" setting
14131      */
14132     private int getUnknownSourcesSettings() {
14133         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14134                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14135                 -1);
14136     }
14137
14138     @Override
14139     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14140         final int uid = Binder.getCallingUid();
14141         // writer
14142         synchronized (mPackages) {
14143             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14144             if (targetPackageSetting == null) {
14145                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14146             }
14147
14148             PackageSetting installerPackageSetting;
14149             if (installerPackageName != null) {
14150                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14151                 if (installerPackageSetting == null) {
14152                     throw new IllegalArgumentException("Unknown installer package: "
14153                             + installerPackageName);
14154                 }
14155             } else {
14156                 installerPackageSetting = null;
14157             }
14158
14159             Signature[] callerSignature;
14160             Object obj = mSettings.getUserIdLPr(uid);
14161             if (obj != null) {
14162                 if (obj instanceof SharedUserSetting) {
14163                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14164                 } else if (obj instanceof PackageSetting) {
14165                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14166                 } else {
14167                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
14168                 }
14169             } else {
14170                 throw new SecurityException("Unknown calling UID: " + uid);
14171             }
14172
14173             // Verify: can't set installerPackageName to a package that is
14174             // not signed with the same cert as the caller.
14175             if (installerPackageSetting != null) {
14176                 if (compareSignatures(callerSignature,
14177                         installerPackageSetting.signatures.mSignatures)
14178                         != PackageManager.SIGNATURE_MATCH) {
14179                     throw new SecurityException(
14180                             "Caller does not have same cert as new installer package "
14181                             + installerPackageName);
14182                 }
14183             }
14184
14185             // Verify: if target already has an installer package, it must
14186             // be signed with the same cert as the caller.
14187             if (targetPackageSetting.installerPackageName != null) {
14188                 PackageSetting setting = mSettings.mPackages.get(
14189                         targetPackageSetting.installerPackageName);
14190                 // If the currently set package isn't valid, then it's always
14191                 // okay to change it.
14192                 if (setting != null) {
14193                     if (compareSignatures(callerSignature,
14194                             setting.signatures.mSignatures)
14195                             != PackageManager.SIGNATURE_MATCH) {
14196                         throw new SecurityException(
14197                                 "Caller does not have same cert as old installer package "
14198                                 + targetPackageSetting.installerPackageName);
14199                     }
14200                 }
14201             }
14202
14203             // Okay!
14204             targetPackageSetting.installerPackageName = installerPackageName;
14205             if (installerPackageName != null) {
14206                 mSettings.mInstallerPackages.add(installerPackageName);
14207             }
14208             scheduleWriteSettingsLocked();
14209         }
14210     }
14211
14212     @Override
14213     public void setApplicationCategoryHint(String packageName, int categoryHint,
14214             String callerPackageName) {
14215         mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14216                 callerPackageName);
14217         synchronized (mPackages) {
14218             PackageSetting ps = mSettings.mPackages.get(packageName);
14219             if (ps == null) {
14220                 throw new IllegalArgumentException("Unknown target package " + packageName);
14221             }
14222
14223             if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14224                 throw new IllegalArgumentException("Calling package " + callerPackageName
14225                         + " is not installer for " + packageName);
14226             }
14227
14228             if (ps.categoryHint != categoryHint) {
14229                 ps.categoryHint = categoryHint;
14230                 scheduleWriteSettingsLocked();
14231             }
14232         }
14233     }
14234
14235     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14236         // Queue up an async operation since the package installation may take a little while.
14237         mHandler.post(new Runnable() {
14238             public void run() {
14239                 mHandler.removeCallbacks(this);
14240                  // Result object to be returned
14241                 PackageInstalledInfo res = new PackageInstalledInfo();
14242                 res.setReturnCode(currentStatus);
14243                 res.uid = -1;
14244                 res.pkg = null;
14245                 res.removedInfo = null;
14246                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14247                     args.doPreInstall(res.returnCode);
14248                     synchronized (mInstallLock) {
14249                         installPackageTracedLI(args, res);
14250                     }
14251                     args.doPostInstall(res.returnCode, res.uid);
14252                 }
14253
14254                 // A restore should be performed at this point if (a) the install
14255                 // succeeded, (b) the operation is not an update, and (c) the new
14256                 // package has not opted out of backup participation.
14257                 final boolean update = res.removedInfo != null
14258                         && res.removedInfo.removedPackage != null;
14259                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14260                 boolean doRestore = !update
14261                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14262
14263                 // Set up the post-install work request bookkeeping.  This will be used
14264                 // and cleaned up by the post-install event handling regardless of whether
14265                 // there's a restore pass performed.  Token values are >= 1.
14266                 int token;
14267                 if (mNextInstallToken < 0) mNextInstallToken = 1;
14268                 token = mNextInstallToken++;
14269
14270                 PostInstallData data = new PostInstallData(args, res);
14271                 mRunningInstalls.put(token, data);
14272                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14273
14274                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14275                     // Pass responsibility to the Backup Manager.  It will perform a
14276                     // restore if appropriate, then pass responsibility back to the
14277                     // Package Manager to run the post-install observer callbacks
14278                     // and broadcasts.
14279                     IBackupManager bm = IBackupManager.Stub.asInterface(
14280                             ServiceManager.getService(Context.BACKUP_SERVICE));
14281                     if (bm != null) {
14282                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14283                                 + " to BM for possible restore");
14284                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14285                         try {
14286                             // TODO: http://b/22388012
14287                             if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14288                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14289                             } else {
14290                                 doRestore = false;
14291                             }
14292                         } catch (RemoteException e) {
14293                             // can't happen; the backup manager is local
14294                         } catch (Exception e) {
14295                             Slog.e(TAG, "Exception trying to enqueue restore", e);
14296                             doRestore = false;
14297                         }
14298                     } else {
14299                         Slog.e(TAG, "Backup Manager not found!");
14300                         doRestore = false;
14301                     }
14302                 }
14303
14304                 if (!doRestore) {
14305                     // No restore possible, or the Backup Manager was mysteriously not
14306                     // available -- just fire the post-install work request directly.
14307                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14308
14309                     Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14310
14311                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14312                     mHandler.sendMessage(msg);
14313                 }
14314             }
14315         });
14316     }
14317
14318     /**
14319      * Callback from PackageSettings whenever an app is first transitioned out of the
14320      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14321      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14322      * here whether the app is the target of an ongoing install, and only send the
14323      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14324      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14325      * handling.
14326      */
14327     void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14328         // Serialize this with the rest of the install-process message chain.  In the
14329         // restore-at-install case, this Runnable will necessarily run before the
14330         // POST_INSTALL message is processed, so the contents of mRunningInstalls
14331         // are coherent.  In the non-restore case, the app has already completed install
14332         // and been launched through some other means, so it is not in a problematic
14333         // state for observers to see the FIRST_LAUNCH signal.
14334         mHandler.post(new Runnable() {
14335             @Override
14336             public void run() {
14337                 for (int i = 0; i < mRunningInstalls.size(); i++) {
14338                     final PostInstallData data = mRunningInstalls.valueAt(i);
14339                     if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14340                         continue;
14341                     }
14342                     if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14343                         // right package; but is it for the right user?
14344                         for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14345                             if (userId == data.res.newUsers[uIndex]) {
14346                                 if (DEBUG_BACKUP) {
14347                                     Slog.i(TAG, "Package " + pkgName
14348                                             + " being restored so deferring FIRST_LAUNCH");
14349                                 }
14350                                 return;
14351                             }
14352                         }
14353                     }
14354                 }
14355                 // didn't find it, so not being restored
14356                 if (DEBUG_BACKUP) {
14357                     Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14358                 }
14359                 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14360             }
14361         });
14362     }
14363
14364     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14365         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14366                 installerPkg, null, userIds);
14367     }
14368
14369     private abstract class HandlerParams {
14370         private static final int MAX_RETRIES = 4;
14371
14372         /**
14373          * Number of times startCopy() has been attempted and had a non-fatal
14374          * error.
14375          */
14376         private int mRetries = 0;
14377
14378         /** User handle for the user requesting the information or installation. */
14379         private final UserHandle mUser;
14380         String traceMethod;
14381         int traceCookie;
14382
14383         HandlerParams(UserHandle user) {
14384             mUser = user;
14385         }
14386
14387         UserHandle getUser() {
14388             return mUser;
14389         }
14390
14391         HandlerParams setTraceMethod(String traceMethod) {
14392             this.traceMethod = traceMethod;
14393             return this;
14394         }
14395
14396         HandlerParams setTraceCookie(int traceCookie) {
14397             this.traceCookie = traceCookie;
14398             return this;
14399         }
14400
14401         final boolean startCopy() {
14402             boolean res;
14403             try {
14404                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14405
14406                 if (++mRetries > MAX_RETRIES) {
14407                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14408                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
14409                     handleServiceError();
14410                     return false;
14411                 } else {
14412                     handleStartCopy();
14413                     res = true;
14414                 }
14415             } catch (RemoteException e) {
14416                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14417                 mHandler.sendEmptyMessage(MCS_RECONNECT);
14418                 res = false;
14419             }
14420             handleReturnCode();
14421             return res;
14422         }
14423
14424         final void serviceError() {
14425             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14426             handleServiceError();
14427             handleReturnCode();
14428         }
14429
14430         abstract void handleStartCopy() throws RemoteException;
14431         abstract void handleServiceError();
14432         abstract void handleReturnCode();
14433     }
14434
14435     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14436         for (File path : paths) {
14437             try {
14438                 mcs.clearDirectory(path.getAbsolutePath());
14439             } catch (RemoteException e) {
14440             }
14441         }
14442     }
14443
14444     static class OriginInfo {
14445         /**
14446          * Location where install is coming from, before it has been
14447          * copied/renamed into place. This could be a single monolithic APK
14448          * file, or a cluster directory. This location may be untrusted.
14449          */
14450         final File file;
14451         final String cid;
14452
14453         /**
14454          * Flag indicating that {@link #file} or {@link #cid} has already been
14455          * staged, meaning downstream users don't need to defensively copy the
14456          * contents.
14457          */
14458         final boolean staged;
14459
14460         /**
14461          * Flag indicating that {@link #file} or {@link #cid} is an already
14462          * installed app that is being moved.
14463          */
14464         final boolean existing;
14465
14466         final String resolvedPath;
14467         final File resolvedFile;
14468
14469         static OriginInfo fromNothing() {
14470             return new OriginInfo(null, null, false, false);
14471         }
14472
14473         static OriginInfo fromUntrustedFile(File file) {
14474             return new OriginInfo(file, null, false, false);
14475         }
14476
14477         static OriginInfo fromExistingFile(File file) {
14478             return new OriginInfo(file, null, false, true);
14479         }
14480
14481         static OriginInfo fromStagedFile(File file) {
14482             return new OriginInfo(file, null, true, false);
14483         }
14484
14485         static OriginInfo fromStagedContainer(String cid) {
14486             return new OriginInfo(null, cid, true, false);
14487         }
14488
14489         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14490             this.file = file;
14491             this.cid = cid;
14492             this.staged = staged;
14493             this.existing = existing;
14494
14495             if (cid != null) {
14496                 resolvedPath = PackageHelper.getSdDir(cid);
14497                 resolvedFile = new File(resolvedPath);
14498             } else if (file != null) {
14499                 resolvedPath = file.getAbsolutePath();
14500                 resolvedFile = file;
14501             } else {
14502                 resolvedPath = null;
14503                 resolvedFile = null;
14504             }
14505         }
14506     }
14507
14508     static class MoveInfo {
14509         final int moveId;
14510         final String fromUuid;
14511         final String toUuid;
14512         final String packageName;
14513         final String dataAppName;
14514         final int appId;
14515         final String seinfo;
14516         final int targetSdkVersion;
14517
14518         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14519                 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14520             this.moveId = moveId;
14521             this.fromUuid = fromUuid;
14522             this.toUuid = toUuid;
14523             this.packageName = packageName;
14524             this.dataAppName = dataAppName;
14525             this.appId = appId;
14526             this.seinfo = seinfo;
14527             this.targetSdkVersion = targetSdkVersion;
14528         }
14529     }
14530
14531     static class VerificationInfo {
14532         /** A constant used to indicate that a uid value is not present. */
14533         public static final int NO_UID = -1;
14534
14535         /** URI referencing where the package was downloaded from. */
14536         final Uri originatingUri;
14537
14538         /** HTTP referrer URI associated with the originatingURI. */
14539         final Uri referrer;
14540
14541         /** UID of the application that the install request originated from. */
14542         final int originatingUid;
14543
14544         /** UID of application requesting the install */
14545         final int installerUid;
14546
14547         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14548             this.originatingUri = originatingUri;
14549             this.referrer = referrer;
14550             this.originatingUid = originatingUid;
14551             this.installerUid = installerUid;
14552         }
14553     }
14554
14555     class InstallParams extends HandlerParams {
14556         final OriginInfo origin;
14557         final MoveInfo move;
14558         final IPackageInstallObserver2 observer;
14559         int installFlags;
14560         final String installerPackageName;
14561         final String volumeUuid;
14562         private InstallArgs mArgs;
14563         private int mRet;
14564         final String packageAbiOverride;
14565         final String[] grantedRuntimePermissions;
14566         final VerificationInfo verificationInfo;
14567         final Certificate[][] certificates;
14568         final int installReason;
14569
14570         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14571                 int installFlags, String installerPackageName, String volumeUuid,
14572                 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14573                 String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14574             super(user);
14575             this.origin = origin;
14576             this.move = move;
14577             this.observer = observer;
14578             this.installFlags = installFlags;
14579             this.installerPackageName = installerPackageName;
14580             this.volumeUuid = volumeUuid;
14581             this.verificationInfo = verificationInfo;
14582             this.packageAbiOverride = packageAbiOverride;
14583             this.grantedRuntimePermissions = grantedPermissions;
14584             this.certificates = certificates;
14585             this.installReason = installReason;
14586         }
14587
14588         @Override
14589         public String toString() {
14590             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14591                     + " file=" + origin.file + " cid=" + origin.cid + "}";
14592         }
14593
14594         private int installLocationPolicy(PackageInfoLite pkgLite) {
14595             String packageName = pkgLite.packageName;
14596             int installLocation = pkgLite.installLocation;
14597             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14598             // reader
14599             synchronized (mPackages) {
14600                 // Currently installed package which the new package is attempting to replace or
14601                 // null if no such package is installed.
14602                 PackageParser.Package installedPkg = mPackages.get(packageName);
14603                 // Package which currently owns the data which the new package will own if installed.
14604                 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14605                 // will be null whereas dataOwnerPkg will contain information about the package
14606                 // which was uninstalled while keeping its data.
14607                 PackageParser.Package dataOwnerPkg = installedPkg;
14608                 if (dataOwnerPkg  == null) {
14609                     PackageSetting ps = mSettings.mPackages.get(packageName);
14610                     if (ps != null) {
14611                         dataOwnerPkg = ps.pkg;
14612                     }
14613                 }
14614
14615                 if (dataOwnerPkg != null) {
14616                     // If installed, the package will get access to data left on the device by its
14617                     // predecessor. As a security measure, this is permited only if this is not a
14618                     // version downgrade or if the predecessor package is marked as debuggable and
14619                     // a downgrade is explicitly requested.
14620                     //
14621                     // On debuggable platform builds, downgrades are permitted even for
14622                     // non-debuggable packages to make testing easier. Debuggable platform builds do
14623                     // not offer security guarantees and thus it's OK to disable some security
14624                     // mechanisms to make debugging/testing easier on those builds. However, even on
14625                     // debuggable builds downgrades of packages are permitted only if requested via
14626                     // installFlags. This is because we aim to keep the behavior of debuggable
14627                     // platform builds as close as possible to the behavior of non-debuggable
14628                     // platform builds.
14629                     final boolean downgradeRequested =
14630                             (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14631                     final boolean packageDebuggable =
14632                                 (dataOwnerPkg.applicationInfo.flags
14633                                         & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14634                     final boolean downgradePermitted =
14635                             (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14636                     if (!downgradePermitted) {
14637                         try {
14638                             checkDowngrade(dataOwnerPkg, pkgLite);
14639                         } catch (PackageManagerException e) {
14640                             Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14641                             return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14642                         }
14643                     }
14644                 }
14645
14646                 if (installedPkg != null) {
14647                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14648                         // Check for updated system application.
14649                         if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14650                             if (onSd) {
14651                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
14652                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14653                             }
14654                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14655                         } else {
14656                             if (onSd) {
14657                                 // Install flag overrides everything.
14658                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14659                             }
14660                             // If current upgrade specifies particular preference
14661                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14662                                 // Application explicitly specified internal.
14663                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14664                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14665                                 // App explictly prefers external. Let policy decide
14666                             } else {
14667                                 // Prefer previous location
14668                                 if (isExternal(installedPkg)) {
14669                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14670                                 }
14671                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14672                             }
14673                         }
14674                     } else {
14675                         // Invalid install. Return error code
14676                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14677                     }
14678                 }
14679             }
14680             // All the special cases have been taken care of.
14681             // Return result based on recommended install location.
14682             if (onSd) {
14683                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14684             }
14685             return pkgLite.recommendedInstallLocation;
14686         }
14687
14688         /*
14689          * Invoke remote method to get package information and install
14690          * location values. Override install location based on default
14691          * policy if needed and then create install arguments based
14692          * on the install location.
14693          */
14694         public void handleStartCopy() throws RemoteException {
14695             int ret = PackageManager.INSTALL_SUCCEEDED;
14696
14697             // If we're already staged, we've firmly committed to an install location
14698             if (origin.staged) {
14699                 if (origin.file != null) {
14700                     installFlags |= PackageManager.INSTALL_INTERNAL;
14701                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14702                 } else if (origin.cid != null) {
14703                     installFlags |= PackageManager.INSTALL_EXTERNAL;
14704                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
14705                 } else {
14706                     throw new IllegalStateException("Invalid stage location");
14707                 }
14708             }
14709
14710             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14711             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14712             final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14713             PackageInfoLite pkgLite = null;
14714
14715             if (onInt && onSd) {
14716                 // Check if both bits are set.
14717                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14718                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14719             } else if (onSd && ephemeral) {
14720                 Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14721                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14722             } else {
14723                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14724                         packageAbiOverride);
14725
14726                 if (DEBUG_EPHEMERAL && ephemeral) {
14727                     Slog.v(TAG, "pkgLite for install: " + pkgLite);
14728                 }
14729
14730                 /*
14731                  * If we have too little free space, try to free cache
14732                  * before giving up.
14733                  */
14734                 if (!origin.staged && pkgLite.recommendedInstallLocation
14735                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14736                     // TODO: focus freeing disk space on the target device
14737                     final StorageManager storage = StorageManager.from(mContext);
14738                     final long lowThreshold = storage.getStorageLowBytes(
14739                             Environment.getDataDirectory());
14740
14741                     final long sizeBytes = mContainerService.calculateInstalledSize(
14742                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
14743
14744                     try {
14745                         mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
14746                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14747                                 installFlags, packageAbiOverride);
14748                     } catch (InstallerException e) {
14749                         Slog.w(TAG, "Failed to free cache", e);
14750                     }
14751
14752                     /*
14753                      * The cache free must have deleted the file we
14754                      * downloaded to install.
14755                      *
14756                      * TODO: fix the "freeCache" call to not delete
14757                      *       the file we care about.
14758                      */
14759                     if (pkgLite.recommendedInstallLocation
14760                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14761                         pkgLite.recommendedInstallLocation
14762                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14763                     }
14764                 }
14765             }
14766
14767             if (ret == PackageManager.INSTALL_SUCCEEDED) {
14768                 int loc = pkgLite.recommendedInstallLocation;
14769                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14770                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14771                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14772                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14773                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14774                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14775                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14776                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14777                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14778                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14779                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14780                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14781                 } else {
14782                     // Override with defaults if needed.
14783                     loc = installLocationPolicy(pkgLite);
14784                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14785                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14786                     } else if (!onSd && !onInt) {
14787                         // Override install location with flags
14788                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14789                             // Set the flag to install on external media.
14790                             installFlags |= PackageManager.INSTALL_EXTERNAL;
14791                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
14792                         } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14793                             if (DEBUG_EPHEMERAL) {
14794                                 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14795                             }
14796                             installFlags |= PackageManager.INSTALL_INSTANT_APP;
14797                             installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14798                                     |PackageManager.INSTALL_INTERNAL);
14799                         } else {
14800                             // Make sure the flag for installing on external
14801                             // media is unset
14802                             installFlags |= PackageManager.INSTALL_INTERNAL;
14803                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14804                         }
14805                     }
14806                 }
14807             }
14808
14809             final InstallArgs args = createInstallArgs(this);
14810             mArgs = args;
14811
14812             if (ret == PackageManager.INSTALL_SUCCEEDED) {
14813                 // TODO: http://b/22976637
14814                 // Apps installed for "all" users use the device owner to verify the app
14815                 UserHandle verifierUser = getUser();
14816                 if (verifierUser == UserHandle.ALL) {
14817                     verifierUser = UserHandle.SYSTEM;
14818                 }
14819
14820                 /*
14821                  * Determine if we have any installed package verifiers. If we
14822                  * do, then we'll defer to them to verify the packages.
14823                  */
14824                 final int requiredUid = mRequiredVerifierPackage == null ? -1
14825                         : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14826                                 verifierUser.getIdentifier());
14827                 if (!origin.existing && requiredUid != -1
14828                         && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
14829                     final Intent verification = new Intent(
14830                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14831                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14832                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14833                             PACKAGE_MIME_TYPE);
14834                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14835
14836                     // Query all live verifiers based on current user state
14837                     final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14838                             PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
14839
14840                     if (DEBUG_VERIFY) {
14841                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14842                                 + verification.toString() + " with " + pkgLite.verifiers.length
14843                                 + " optional verifiers");
14844                     }
14845
14846                     final int verificationId = mPendingVerificationToken++;
14847
14848                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14849
14850                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14851                             installerPackageName);
14852
14853                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14854                             installFlags);
14855
14856                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14857                             pkgLite.packageName);
14858
14859                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14860                             pkgLite.versionCode);
14861
14862                     if (verificationInfo != null) {
14863                         if (verificationInfo.originatingUri != null) {
14864                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14865                                     verificationInfo.originatingUri);
14866                         }
14867                         if (verificationInfo.referrer != null) {
14868                             verification.putExtra(Intent.EXTRA_REFERRER,
14869                                     verificationInfo.referrer);
14870                         }
14871                         if (verificationInfo.originatingUid >= 0) {
14872                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14873                                     verificationInfo.originatingUid);
14874                         }
14875                         if (verificationInfo.installerUid >= 0) {
14876                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14877                                     verificationInfo.installerUid);
14878                         }
14879                     }
14880
14881                     final PackageVerificationState verificationState = new PackageVerificationState(
14882                             requiredUid, args);
14883
14884                     mPendingVerification.append(verificationId, verificationState);
14885
14886                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14887                             receivers, verificationState);
14888
14889                     DeviceIdleController.LocalService idleController = getDeviceIdleController();
14890                     final long idleDuration = getVerificationTimeout();
14891
14892                     /*
14893                      * If any sufficient verifiers were listed in the package
14894                      * manifest, attempt to ask them.
14895                      */
14896                     if (sufficientVerifiers != null) {
14897                         final int N = sufficientVerifiers.size();
14898                         if (N == 0) {
14899                             Slog.i(TAG, "Additional verifiers required, but none installed.");
14900                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14901                         } else {
14902                             for (int i = 0; i < N; i++) {
14903                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
14904                                 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14905                                         verifierComponent.getPackageName(), idleDuration,
14906                                         verifierUser.getIdentifier(), false, "package verifier");
14907
14908                                 final Intent sufficientIntent = new Intent(verification);
14909                                 sufficientIntent.setComponent(verifierComponent);
14910                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14911                             }
14912                         }
14913                     }
14914
14915                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14916                             mRequiredVerifierPackage, receivers);
14917                     if (ret == PackageManager.INSTALL_SUCCEEDED
14918                             && mRequiredVerifierPackage != null) {
14919                         Trace.asyncTraceBegin(
14920                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14921                         /*
14922                          * Send the intent to the required verification agent,
14923                          * but only start the verification timeout after the
14924                          * target BroadcastReceivers have run.
14925                          */
14926                         verification.setComponent(requiredVerifierComponent);
14927                         idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14928                                 mRequiredVerifierPackage, idleDuration,
14929                                 verifierUser.getIdentifier(), false, "package verifier");
14930                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14931                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14932                                 new BroadcastReceiver() {
14933                                     @Override
14934                                     public void onReceive(Context context, Intent intent) {
14935                                         final Message msg = mHandler
14936                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
14937                                         msg.arg1 = verificationId;
14938                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14939                                     }
14940                                 }, null, 0, null, null);
14941
14942                         /*
14943                          * We don't want the copy to proceed until verification
14944                          * succeeds, so null out this field.
14945                          */
14946                         mArgs = null;
14947                     }
14948                 } else {
14949                     /*
14950                      * No package verification is enabled, so immediately start
14951                      * the remote call to initiate copy using temporary file.
14952                      */
14953                     ret = args.copyApk(mContainerService, true);
14954                 }
14955             }
14956
14957             mRet = ret;
14958         }
14959
14960         @Override
14961         void handleReturnCode() {
14962             // If mArgs is null, then MCS couldn't be reached. When it
14963             // reconnects, it will try again to install. At that point, this
14964             // will succeed.
14965             if (mArgs != null) {
14966                 processPendingInstall(mArgs, mRet);
14967             }
14968         }
14969
14970         @Override
14971         void handleServiceError() {
14972             mArgs = createInstallArgs(this);
14973             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14974         }
14975
14976         public boolean isForwardLocked() {
14977             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14978         }
14979     }
14980
14981     /**
14982      * Used during creation of InstallArgs
14983      *
14984      * @param installFlags package installation flags
14985      * @return true if should be installed on external storage
14986      */
14987     private static boolean installOnExternalAsec(int installFlags) {
14988         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
14989             return false;
14990         }
14991         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14992             return true;
14993         }
14994         return false;
14995     }
14996
14997     /**
14998      * Used during creation of InstallArgs
14999      *
15000      * @param installFlags package installation flags
15001      * @return true if should be installed as forward locked
15002      */
15003     private static boolean installForwardLocked(int installFlags) {
15004         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15005     }
15006
15007     private InstallArgs createInstallArgs(InstallParams params) {
15008         if (params.move != null) {
15009             return new MoveInstallArgs(params);
15010         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15011             return new AsecInstallArgs(params);
15012         } else {
15013             return new FileInstallArgs(params);
15014         }
15015     }
15016
15017     /**
15018      * Create args that describe an existing installed package. Typically used
15019      * when cleaning up old installs, or used as a move source.
15020      */
15021     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15022             String resourcePath, String[] instructionSets) {
15023         final boolean isInAsec;
15024         if (installOnExternalAsec(installFlags)) {
15025             /* Apps on SD card are always in ASEC containers. */
15026             isInAsec = true;
15027         } else if (installForwardLocked(installFlags)
15028                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15029             /*
15030              * Forward-locked apps are only in ASEC containers if they're the
15031              * new style
15032              */
15033             isInAsec = true;
15034         } else {
15035             isInAsec = false;
15036         }
15037
15038         if (isInAsec) {
15039             return new AsecInstallArgs(codePath, instructionSets,
15040                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15041         } else {
15042             return new FileInstallArgs(codePath, resourcePath, instructionSets);
15043         }
15044     }
15045
15046     static abstract class InstallArgs {
15047         /** @see InstallParams#origin */
15048         final OriginInfo origin;
15049         /** @see InstallParams#move */
15050         final MoveInfo move;
15051
15052         final IPackageInstallObserver2 observer;
15053         // Always refers to PackageManager flags only
15054         final int installFlags;
15055         final String installerPackageName;
15056         final String volumeUuid;
15057         final UserHandle user;
15058         final String abiOverride;
15059         final String[] installGrantPermissions;
15060         /** If non-null, drop an async trace when the install completes */
15061         final String traceMethod;
15062         final int traceCookie;
15063         final Certificate[][] certificates;
15064         final int installReason;
15065
15066         // The list of instruction sets supported by this app. This is currently
15067         // only used during the rmdex() phase to clean up resources. We can get rid of this
15068         // if we move dex files under the common app path.
15069         /* nullable */ String[] instructionSets;
15070
15071         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15072                 int installFlags, String installerPackageName, String volumeUuid,
15073                 UserHandle user, String[] instructionSets,
15074                 String abiOverride, String[] installGrantPermissions,
15075                 String traceMethod, int traceCookie, Certificate[][] certificates,
15076                 int installReason) {
15077             this.origin = origin;
15078             this.move = move;
15079             this.installFlags = installFlags;
15080             this.observer = observer;
15081             this.installerPackageName = installerPackageName;
15082             this.volumeUuid = volumeUuid;
15083             this.user = user;
15084             this.instructionSets = instructionSets;
15085             this.abiOverride = abiOverride;
15086             this.installGrantPermissions = installGrantPermissions;
15087             this.traceMethod = traceMethod;
15088             this.traceCookie = traceCookie;
15089             this.certificates = certificates;
15090             this.installReason = installReason;
15091         }
15092
15093         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15094         abstract int doPreInstall(int status);
15095
15096         /**
15097          * Rename package into final resting place. All paths on the given
15098          * scanned package should be updated to reflect the rename.
15099          */
15100         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15101         abstract int doPostInstall(int status, int uid);
15102
15103         /** @see PackageSettingBase#codePathString */
15104         abstract String getCodePath();
15105         /** @see PackageSettingBase#resourcePathString */
15106         abstract String getResourcePath();
15107
15108         // Need installer lock especially for dex file removal.
15109         abstract void cleanUpResourcesLI();
15110         abstract boolean doPostDeleteLI(boolean delete);
15111
15112         /**
15113          * Called before the source arguments are copied. This is used mostly
15114          * for MoveParams when it needs to read the source file to put it in the
15115          * destination.
15116          */
15117         int doPreCopy() {
15118             return PackageManager.INSTALL_SUCCEEDED;
15119         }
15120
15121         /**
15122          * Called after the source arguments are copied. This is used mostly for
15123          * MoveParams when it needs to read the source file to put it in the
15124          * destination.
15125          */
15126         int doPostCopy(int uid) {
15127             return PackageManager.INSTALL_SUCCEEDED;
15128         }
15129
15130         protected boolean isFwdLocked() {
15131             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15132         }
15133
15134         protected boolean isExternalAsec() {
15135             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15136         }
15137
15138         protected boolean isEphemeral() {
15139             return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15140         }
15141
15142         UserHandle getUser() {
15143             return user;
15144         }
15145     }
15146
15147     private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15148         if (!allCodePaths.isEmpty()) {
15149             if (instructionSets == null) {
15150                 throw new IllegalStateException("instructionSet == null");
15151             }
15152             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15153             for (String codePath : allCodePaths) {
15154                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15155                     try {
15156                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
15157                     } catch (InstallerException ignored) {
15158                     }
15159                 }
15160             }
15161         }
15162     }
15163
15164     /**
15165      * Logic to handle installation of non-ASEC applications, including copying
15166      * and renaming logic.
15167      */
15168     class FileInstallArgs extends InstallArgs {
15169         private File codeFile;
15170         private File resourceFile;
15171
15172         // Example topology:
15173         // /data/app/com.example/base.apk
15174         // /data/app/com.example/split_foo.apk
15175         // /data/app/com.example/lib/arm/libfoo.so
15176         // /data/app/com.example/lib/arm64/libfoo.so
15177         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15178
15179         /** New install */
15180         FileInstallArgs(InstallParams params) {
15181             super(params.origin, params.move, params.observer, params.installFlags,
15182                     params.installerPackageName, params.volumeUuid,
15183                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15184                     params.grantedRuntimePermissions,
15185                     params.traceMethod, params.traceCookie, params.certificates,
15186                     params.installReason);
15187             if (isFwdLocked()) {
15188                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
15189             }
15190         }
15191
15192         /** Existing install */
15193         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15194             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15195                     null, null, null, 0, null /*certificates*/,
15196                     PackageManager.INSTALL_REASON_UNKNOWN);
15197             this.codeFile = (codePath != null) ? new File(codePath) : null;
15198             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15199         }
15200
15201         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15202             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15203             try {
15204                 return doCopyApk(imcs, temp);
15205             } finally {
15206                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15207             }
15208         }
15209
15210         private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15211             if (origin.staged) {
15212                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15213                 codeFile = origin.file;
15214                 resourceFile = origin.file;
15215                 return PackageManager.INSTALL_SUCCEEDED;
15216             }
15217
15218             try {
15219                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15220                 final File tempDir =
15221                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15222                 codeFile = tempDir;
15223                 resourceFile = tempDir;
15224             } catch (IOException e) {
15225                 Slog.w(TAG, "Failed to create copy file: " + e);
15226                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15227             }
15228
15229             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15230                 @Override
15231                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15232                     if (!FileUtils.isValidExtFilename(name)) {
15233                         throw new IllegalArgumentException("Invalid filename: " + name);
15234                     }
15235                     try {
15236                         final File file = new File(codeFile, name);
15237                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15238                                 O_RDWR | O_CREAT, 0644);
15239                         Os.chmod(file.getAbsolutePath(), 0644);
15240                         return new ParcelFileDescriptor(fd);
15241                     } catch (ErrnoException e) {
15242                         throw new RemoteException("Failed to open: " + e.getMessage());
15243                     }
15244                 }
15245             };
15246
15247             int ret = PackageManager.INSTALL_SUCCEEDED;
15248             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15249             if (ret != PackageManager.INSTALL_SUCCEEDED) {
15250                 Slog.e(TAG, "Failed to copy package");
15251                 return ret;
15252             }
15253
15254             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15255             NativeLibraryHelper.Handle handle = null;
15256             try {
15257                 handle = NativeLibraryHelper.Handle.create(codeFile);
15258                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15259                         abiOverride);
15260             } catch (IOException e) {
15261                 Slog.e(TAG, "Copying native libraries failed", e);
15262                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15263             } finally {
15264                 IoUtils.closeQuietly(handle);
15265             }
15266
15267             return ret;
15268         }
15269
15270         int doPreInstall(int status) {
15271             if (status != PackageManager.INSTALL_SUCCEEDED) {
15272                 cleanUp();
15273             }
15274             return status;
15275         }
15276
15277         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15278             if (status != PackageManager.INSTALL_SUCCEEDED) {
15279                 cleanUp();
15280                 return false;
15281             }
15282
15283             final File targetDir = codeFile.getParentFile();
15284             final File beforeCodeFile = codeFile;
15285             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15286
15287             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15288             try {
15289                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15290             } catch (ErrnoException e) {
15291                 Slog.w(TAG, "Failed to rename", e);
15292                 return false;
15293             }
15294
15295             if (!SELinux.restoreconRecursive(afterCodeFile)) {
15296                 Slog.w(TAG, "Failed to restorecon");
15297                 return false;
15298             }
15299
15300             // Reflect the rename internally
15301             codeFile = afterCodeFile;
15302             resourceFile = afterCodeFile;
15303
15304             // Reflect the rename in scanned details
15305             pkg.setCodePath(afterCodeFile.getAbsolutePath());
15306             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15307                     afterCodeFile, pkg.baseCodePath));
15308             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15309                     afterCodeFile, pkg.splitCodePaths));
15310
15311             // Reflect the rename in app info
15312             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15313             pkg.setApplicationInfoCodePath(pkg.codePath);
15314             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15315             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15316             pkg.setApplicationInfoResourcePath(pkg.codePath);
15317             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15318             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15319
15320             return true;
15321         }
15322
15323         int doPostInstall(int status, int uid) {
15324             if (status != PackageManager.INSTALL_SUCCEEDED) {
15325                 cleanUp();
15326             }
15327             return status;
15328         }
15329
15330         @Override
15331         String getCodePath() {
15332             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15333         }
15334
15335         @Override
15336         String getResourcePath() {
15337             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15338         }
15339
15340         private boolean cleanUp() {
15341             if (codeFile == null || !codeFile.exists()) {
15342                 return false;
15343             }
15344
15345             removeCodePathLI(codeFile);
15346
15347             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15348                 resourceFile.delete();
15349             }
15350
15351             return true;
15352         }
15353
15354         void cleanUpResourcesLI() {
15355             // Try enumerating all code paths before deleting
15356             List<String> allCodePaths = Collections.EMPTY_LIST;
15357             if (codeFile != null && codeFile.exists()) {
15358                 try {
15359                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15360                     allCodePaths = pkg.getAllCodePaths();
15361                 } catch (PackageParserException e) {
15362                     // Ignored; we tried our best
15363                 }
15364             }
15365
15366             cleanUp();
15367             removeDexFiles(allCodePaths, instructionSets);
15368         }
15369
15370         boolean doPostDeleteLI(boolean delete) {
15371             // XXX err, shouldn't we respect the delete flag?
15372             cleanUpResourcesLI();
15373             return true;
15374         }
15375     }
15376
15377     private boolean isAsecExternal(String cid) {
15378         final String asecPath = PackageHelper.getSdFilesystem(cid);
15379         return !asecPath.startsWith(mAsecInternalPath);
15380     }
15381
15382     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15383             PackageManagerException {
15384         if (copyRet < 0) {
15385             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15386                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15387                 throw new PackageManagerException(copyRet, message);
15388             }
15389         }
15390     }
15391
15392     /**
15393      * Extract the StorageManagerService "container ID" from the full code path of an
15394      * .apk.
15395      */
15396     static String cidFromCodePath(String fullCodePath) {
15397         int eidx = fullCodePath.lastIndexOf("/");
15398         String subStr1 = fullCodePath.substring(0, eidx);
15399         int sidx = subStr1.lastIndexOf("/");
15400         return subStr1.substring(sidx+1, eidx);
15401     }
15402
15403     /**
15404      * Logic to handle installation of ASEC applications, including copying and
15405      * renaming logic.
15406      */
15407     class AsecInstallArgs extends InstallArgs {
15408         static final String RES_FILE_NAME = "pkg.apk";
15409         static final String PUBLIC_RES_FILE_NAME = "res.zip";
15410
15411         String cid;
15412         String packagePath;
15413         String resourcePath;
15414
15415         /** New install */
15416         AsecInstallArgs(InstallParams params) {
15417             super(params.origin, params.move, params.observer, params.installFlags,
15418                     params.installerPackageName, params.volumeUuid,
15419                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15420                     params.grantedRuntimePermissions,
15421                     params.traceMethod, params.traceCookie, params.certificates,
15422                     params.installReason);
15423         }
15424
15425         /** Existing install */
15426         AsecInstallArgs(String fullCodePath, String[] instructionSets,
15427                         boolean isExternal, boolean isForwardLocked) {
15428             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15429                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15430                     instructionSets, null, null, null, 0, null /*certificates*/,
15431                     PackageManager.INSTALL_REASON_UNKNOWN);
15432             // Hackily pretend we're still looking at a full code path
15433             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15434                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15435             }
15436
15437             // Extract cid from fullCodePath
15438             int eidx = fullCodePath.lastIndexOf("/");
15439             String subStr1 = fullCodePath.substring(0, eidx);
15440             int sidx = subStr1.lastIndexOf("/");
15441             cid = subStr1.substring(sidx+1, eidx);
15442             setMountPath(subStr1);
15443         }
15444
15445         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15446             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15447                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15448                     instructionSets, null, null, null, 0, null /*certificates*/,
15449                     PackageManager.INSTALL_REASON_UNKNOWN);
15450             this.cid = cid;
15451             setMountPath(PackageHelper.getSdDir(cid));
15452         }
15453
15454         void createCopyFile() {
15455             cid = mInstallerService.allocateExternalStageCidLegacy();
15456         }
15457
15458         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15459             if (origin.staged && origin.cid != null) {
15460                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15461                 cid = origin.cid;
15462                 setMountPath(PackageHelper.getSdDir(cid));
15463                 return PackageManager.INSTALL_SUCCEEDED;
15464             }
15465
15466             if (temp) {
15467                 createCopyFile();
15468             } else {
15469                 /*
15470                  * Pre-emptively destroy the container since it's destroyed if
15471                  * copying fails due to it existing anyway.
15472                  */
15473                 PackageHelper.destroySdDir(cid);
15474             }
15475
15476             final String newMountPath = imcs.copyPackageToContainer(
15477                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15478                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15479
15480             if (newMountPath != null) {
15481                 setMountPath(newMountPath);
15482                 return PackageManager.INSTALL_SUCCEEDED;
15483             } else {
15484                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15485             }
15486         }
15487
15488         @Override
15489         String getCodePath() {
15490             return packagePath;
15491         }
15492
15493         @Override
15494         String getResourcePath() {
15495             return resourcePath;
15496         }
15497
15498         int doPreInstall(int status) {
15499             if (status != PackageManager.INSTALL_SUCCEEDED) {
15500                 // Destroy container
15501                 PackageHelper.destroySdDir(cid);
15502             } else {
15503                 boolean mounted = PackageHelper.isContainerMounted(cid);
15504                 if (!mounted) {
15505                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15506                             Process.SYSTEM_UID);
15507                     if (newMountPath != null) {
15508                         setMountPath(newMountPath);
15509                     } else {
15510                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15511                     }
15512                 }
15513             }
15514             return status;
15515         }
15516
15517         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15518             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15519             String newMountPath = null;
15520             if (PackageHelper.isContainerMounted(cid)) {
15521                 // Unmount the container
15522                 if (!PackageHelper.unMountSdDir(cid)) {
15523                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15524                     return false;
15525                 }
15526             }
15527             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15528                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15529                         " which might be stale. Will try to clean up.");
15530                 // Clean up the stale container and proceed to recreate.
15531                 if (!PackageHelper.destroySdDir(newCacheId)) {
15532                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15533                     return false;
15534                 }
15535                 // Successfully cleaned up stale container. Try to rename again.
15536                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15537                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15538                             + " inspite of cleaning it up.");
15539                     return false;
15540                 }
15541             }
15542             if (!PackageHelper.isContainerMounted(newCacheId)) {
15543                 Slog.w(TAG, "Mounting container " + newCacheId);
15544                 newMountPath = PackageHelper.mountSdDir(newCacheId,
15545                         getEncryptKey(), Process.SYSTEM_UID);
15546             } else {
15547                 newMountPath = PackageHelper.getSdDir(newCacheId);
15548             }
15549             if (newMountPath == null) {
15550                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
15551                 return false;
15552             }
15553             Log.i(TAG, "Succesfully renamed " + cid +
15554                     " to " + newCacheId +
15555                     " at new path: " + newMountPath);
15556             cid = newCacheId;
15557
15558             final File beforeCodeFile = new File(packagePath);
15559             setMountPath(newMountPath);
15560             final File afterCodeFile = new File(packagePath);
15561
15562             // Reflect the rename in scanned details
15563             pkg.setCodePath(afterCodeFile.getAbsolutePath());
15564             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15565                     afterCodeFile, pkg.baseCodePath));
15566             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15567                     afterCodeFile, pkg.splitCodePaths));
15568
15569             // Reflect the rename in app info
15570             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15571             pkg.setApplicationInfoCodePath(pkg.codePath);
15572             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15573             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15574             pkg.setApplicationInfoResourcePath(pkg.codePath);
15575             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15576             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15577
15578             return true;
15579         }
15580
15581         private void setMountPath(String mountPath) {
15582             final File mountFile = new File(mountPath);
15583
15584             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
15585             if (monolithicFile.exists()) {
15586                 packagePath = monolithicFile.getAbsolutePath();
15587                 if (isFwdLocked()) {
15588                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
15589                 } else {
15590                     resourcePath = packagePath;
15591                 }
15592             } else {
15593                 packagePath = mountFile.getAbsolutePath();
15594                 resourcePath = packagePath;
15595             }
15596         }
15597
15598         int doPostInstall(int status, int uid) {
15599             if (status != PackageManager.INSTALL_SUCCEEDED) {
15600                 cleanUp();
15601             } else {
15602                 final int groupOwner;
15603                 final String protectedFile;
15604                 if (isFwdLocked()) {
15605                     groupOwner = UserHandle.getSharedAppGid(uid);
15606                     protectedFile = RES_FILE_NAME;
15607                 } else {
15608                     groupOwner = -1;
15609                     protectedFile = null;
15610                 }
15611
15612                 if (uid < Process.FIRST_APPLICATION_UID
15613                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
15614                     Slog.e(TAG, "Failed to finalize " + cid);
15615                     PackageHelper.destroySdDir(cid);
15616                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15617                 }
15618
15619                 boolean mounted = PackageHelper.isContainerMounted(cid);
15620                 if (!mounted) {
15621                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
15622                 }
15623             }
15624             return status;
15625         }
15626
15627         private void cleanUp() {
15628             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
15629
15630             // Destroy secure container
15631             PackageHelper.destroySdDir(cid);
15632         }
15633
15634         private List<String> getAllCodePaths() {
15635             final File codeFile = new File(getCodePath());
15636             if (codeFile != null && codeFile.exists()) {
15637                 try {
15638                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15639                     return pkg.getAllCodePaths();
15640                 } catch (PackageParserException e) {
15641                     // Ignored; we tried our best
15642                 }
15643             }
15644             return Collections.EMPTY_LIST;
15645         }
15646
15647         void cleanUpResourcesLI() {
15648             // Enumerate all code paths before deleting
15649             cleanUpResourcesLI(getAllCodePaths());
15650         }
15651
15652         private void cleanUpResourcesLI(List<String> allCodePaths) {
15653             cleanUp();
15654             removeDexFiles(allCodePaths, instructionSets);
15655         }
15656
15657         String getPackageName() {
15658             return getAsecPackageName(cid);
15659         }
15660
15661         boolean doPostDeleteLI(boolean delete) {
15662             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
15663             final List<String> allCodePaths = getAllCodePaths();
15664             boolean mounted = PackageHelper.isContainerMounted(cid);
15665             if (mounted) {
15666                 // Unmount first
15667                 if (PackageHelper.unMountSdDir(cid)) {
15668                     mounted = false;
15669                 }
15670             }
15671             if (!mounted && delete) {
15672                 cleanUpResourcesLI(allCodePaths);
15673             }
15674             return !mounted;
15675         }
15676
15677         @Override
15678         int doPreCopy() {
15679             if (isFwdLocked()) {
15680                 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
15681                         MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
15682                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15683                 }
15684             }
15685
15686             return PackageManager.INSTALL_SUCCEEDED;
15687         }
15688
15689         @Override
15690         int doPostCopy(int uid) {
15691             if (isFwdLocked()) {
15692                 if (uid < Process.FIRST_APPLICATION_UID
15693                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
15694                                 RES_FILE_NAME)) {
15695                     Slog.e(TAG, "Failed to finalize " + cid);
15696                     PackageHelper.destroySdDir(cid);
15697                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15698                 }
15699             }
15700
15701             return PackageManager.INSTALL_SUCCEEDED;
15702         }
15703     }
15704
15705     /**
15706      * Logic to handle movement of existing installed applications.
15707      */
15708     class MoveInstallArgs extends InstallArgs {
15709         private File codeFile;
15710         private File resourceFile;
15711
15712         /** New install */
15713         MoveInstallArgs(InstallParams params) {
15714             super(params.origin, params.move, params.observer, params.installFlags,
15715                     params.installerPackageName, params.volumeUuid,
15716                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15717                     params.grantedRuntimePermissions,
15718                     params.traceMethod, params.traceCookie, params.certificates,
15719                     params.installReason);
15720         }
15721
15722         int copyApk(IMediaContainerService imcs, boolean temp) {
15723             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15724                     + move.fromUuid + " to " + move.toUuid);
15725             synchronized (mInstaller) {
15726                 try {
15727                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15728                             move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15729                 } catch (InstallerException e) {
15730                     Slog.w(TAG, "Failed to move app", e);
15731                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15732                 }
15733             }
15734
15735             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15736             resourceFile = codeFile;
15737             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15738
15739             return PackageManager.INSTALL_SUCCEEDED;
15740         }
15741
15742         int doPreInstall(int status) {
15743             if (status != PackageManager.INSTALL_SUCCEEDED) {
15744                 cleanUp(move.toUuid);
15745             }
15746             return status;
15747         }
15748
15749         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15750             if (status != PackageManager.INSTALL_SUCCEEDED) {
15751                 cleanUp(move.toUuid);
15752                 return false;
15753             }
15754
15755             // Reflect the move in app info
15756             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15757             pkg.setApplicationInfoCodePath(pkg.codePath);
15758             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15759             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15760             pkg.setApplicationInfoResourcePath(pkg.codePath);
15761             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15762             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15763
15764             return true;
15765         }
15766
15767         int doPostInstall(int status, int uid) {
15768             if (status == PackageManager.INSTALL_SUCCEEDED) {
15769                 cleanUp(move.fromUuid);
15770             } else {
15771                 cleanUp(move.toUuid);
15772             }
15773             return status;
15774         }
15775
15776         @Override
15777         String getCodePath() {
15778             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15779         }
15780
15781         @Override
15782         String getResourcePath() {
15783             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15784         }
15785
15786         private boolean cleanUp(String volumeUuid) {
15787             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15788                     move.dataAppName);
15789             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15790             final int[] userIds = sUserManager.getUserIds();
15791             synchronized (mInstallLock) {
15792                 // Clean up both app data and code
15793                 // All package moves are frozen until finished
15794                 for (int userId : userIds) {
15795                     try {
15796                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15797                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15798                     } catch (InstallerException e) {
15799                         Slog.w(TAG, String.valueOf(e));
15800                     }
15801                 }
15802                 removeCodePathLI(codeFile);
15803             }
15804             return true;
15805         }
15806
15807         void cleanUpResourcesLI() {
15808             throw new UnsupportedOperationException();
15809         }
15810
15811         boolean doPostDeleteLI(boolean delete) {
15812             throw new UnsupportedOperationException();
15813         }
15814     }
15815
15816     static String getAsecPackageName(String packageCid) {
15817         int idx = packageCid.lastIndexOf("-");
15818         if (idx == -1) {
15819             return packageCid;
15820         }
15821         return packageCid.substring(0, idx);
15822     }
15823
15824     // Utility method used to create code paths based on package name and available index.
15825     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15826         String idxStr = "";
15827         int idx = 1;
15828         // Fall back to default value of idx=1 if prefix is not
15829         // part of oldCodePath
15830         if (oldCodePath != null) {
15831             String subStr = oldCodePath;
15832             // Drop the suffix right away
15833             if (suffix != null && subStr.endsWith(suffix)) {
15834                 subStr = subStr.substring(0, subStr.length() - suffix.length());
15835             }
15836             // If oldCodePath already contains prefix find out the
15837             // ending index to either increment or decrement.
15838             int sidx = subStr.lastIndexOf(prefix);
15839             if (sidx != -1) {
15840                 subStr = subStr.substring(sidx + prefix.length());
15841                 if (subStr != null) {
15842                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15843                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15844                     }
15845                     try {
15846                         idx = Integer.parseInt(subStr);
15847                         if (idx <= 1) {
15848                             idx++;
15849                         } else {
15850                             idx--;
15851                         }
15852                     } catch(NumberFormatException e) {
15853                     }
15854                 }
15855             }
15856         }
15857         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15858         return prefix + idxStr;
15859     }
15860
15861     private File getNextCodePath(File targetDir, String packageName) {
15862         File result;
15863         SecureRandom random = new SecureRandom();
15864         byte[] bytes = new byte[16];
15865         do {
15866             random.nextBytes(bytes);
15867             String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15868             result = new File(targetDir, packageName + "-" + suffix);
15869         } while (result.exists());
15870         return result;
15871     }
15872
15873     // Utility method that returns the relative package path with respect
15874     // to the installation directory. Like say for /data/data/com.test-1.apk
15875     // string com.test-1 is returned.
15876     static String deriveCodePathName(String codePath) {
15877         if (codePath == null) {
15878             return null;
15879         }
15880         final File codeFile = new File(codePath);
15881         final String name = codeFile.getName();
15882         if (codeFile.isDirectory()) {
15883             return name;
15884         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15885             final int lastDot = name.lastIndexOf('.');
15886             return name.substring(0, lastDot);
15887         } else {
15888             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15889             return null;
15890         }
15891     }
15892
15893     static class PackageInstalledInfo {
15894         String name;
15895         int uid;
15896         // The set of users that originally had this package installed.
15897         int[] origUsers;
15898         // The set of users that now have this package installed.
15899         int[] newUsers;
15900         PackageParser.Package pkg;
15901         int returnCode;
15902         String returnMsg;
15903         PackageRemovedInfo removedInfo;
15904         ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15905
15906         public void setError(int code, String msg) {
15907             setReturnCode(code);
15908             setReturnMessage(msg);
15909             Slog.w(TAG, msg);
15910         }
15911
15912         public void setError(String msg, PackageParserException e) {
15913             setReturnCode(e.error);
15914             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15915             Slog.w(TAG, msg, e);
15916         }
15917
15918         public void setError(String msg, PackageManagerException e) {
15919             returnCode = e.error;
15920             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15921             Slog.w(TAG, msg, e);
15922         }
15923
15924         public void setReturnCode(int returnCode) {
15925             this.returnCode = returnCode;
15926             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15927             for (int i = 0; i < childCount; i++) {
15928                 addedChildPackages.valueAt(i).returnCode = returnCode;
15929             }
15930         }
15931
15932         private void setReturnMessage(String returnMsg) {
15933             this.returnMsg = returnMsg;
15934             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15935             for (int i = 0; i < childCount; i++) {
15936                 addedChildPackages.valueAt(i).returnMsg = returnMsg;
15937             }
15938         }
15939
15940         // In some error cases we want to convey more info back to the observer
15941         String origPackage;
15942         String origPermission;
15943     }
15944
15945     /*
15946      * Install a non-existing package.
15947      */
15948     private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
15949             int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
15950             PackageInstalledInfo res, int installReason) {
15951         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15952
15953         // Remember this for later, in case we need to rollback this install
15954         String pkgName = pkg.packageName;
15955
15956         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15957
15958         synchronized(mPackages) {
15959             final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15960             if (renamedPackage != null) {
15961                 // A package with the same name is already installed, though
15962                 // it has been renamed to an older name.  The package we
15963                 // are trying to install should be installed as an update to
15964                 // the existing one, but that has not been requested, so bail.
15965                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15966                         + " without first uninstalling package running as "
15967                         + renamedPackage);
15968                 return;
15969             }
15970             if (mPackages.containsKey(pkgName)) {
15971                 // Don't allow installation over an existing package with the same name.
15972                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15973                         + " without first uninstalling.");
15974                 return;
15975             }
15976         }
15977
15978         try {
15979             PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
15980                     System.currentTimeMillis(), user);
15981
15982             updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15983
15984             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15985                 prepareAppDataAfterInstallLIF(newPackage);
15986
15987             } else {
15988                 // Remove package from internal structures, but keep around any
15989                 // data that might have already existed
15990                 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15991                         PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15992             }
15993         } catch (PackageManagerException e) {
15994             res.setError("Package couldn't be installed in " + pkg.codePath, e);
15995         }
15996
15997         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15998     }
15999
16000     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16001         // Can't rotate keys during boot or if sharedUser.
16002         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16003                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16004             return false;
16005         }
16006         // app is using upgradeKeySets; make sure all are valid
16007         KeySetManagerService ksms = mSettings.mKeySetManagerService;
16008         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16009         for (int i = 0; i < upgradeKeySets.length; i++) {
16010             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16011                 Slog.wtf(TAG, "Package "
16012                          + (oldPs.name != null ? oldPs.name : "<null>")
16013                          + " contains upgrade-key-set reference to unknown key-set: "
16014                          + upgradeKeySets[i]
16015                          + " reverting to signatures check.");
16016                 return false;
16017             }
16018         }
16019         return true;
16020     }
16021
16022     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16023         // Upgrade keysets are being used.  Determine if new package has a superset of the
16024         // required keys.
16025         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16026         KeySetManagerService ksms = mSettings.mKeySetManagerService;
16027         for (int i = 0; i < upgradeKeySets.length; i++) {
16028             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16029             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16030                 return true;
16031             }
16032         }
16033         return false;
16034     }
16035
16036     private static void updateDigest(MessageDigest digest, File file) throws IOException {
16037         try (DigestInputStream digestStream =
16038                 new DigestInputStream(new FileInputStream(file), digest)) {
16039             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16040         }
16041     }
16042
16043     private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16044             UserHandle user, String installerPackageName, PackageInstalledInfo res,
16045             int installReason) {
16046         final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16047
16048         final PackageParser.Package oldPackage;
16049         final String pkgName = pkg.packageName;
16050         final int[] allUsers;
16051         final int[] installedUsers;
16052
16053         synchronized(mPackages) {
16054             oldPackage = mPackages.get(pkgName);
16055             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16056
16057             // don't allow upgrade to target a release SDK from a pre-release SDK
16058             final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16059                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16060             final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16061                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16062             if (oldTargetsPreRelease
16063                     && !newTargetsPreRelease
16064                     && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16065                 Slog.w(TAG, "Can't install package targeting released sdk");
16066                 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16067                 return;
16068             }
16069
16070             final PackageSetting ps = mSettings.mPackages.get(pkgName);
16071
16072             // verify signatures are valid
16073             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16074                 if (!checkUpgradeKeySetLP(ps, pkg)) {
16075                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16076                             "New package not signed by keys specified by upgrade-keysets: "
16077                                     + pkgName);
16078                     return;
16079                 }
16080             } else {
16081                 // default to original signature matching
16082                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16083                         != PackageManager.SIGNATURE_MATCH) {
16084                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16085                             "New package has a different signature: " + pkgName);
16086                     return;
16087                 }
16088             }
16089
16090             // don't allow a system upgrade unless the upgrade hash matches
16091             if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16092                 byte[] digestBytes = null;
16093                 try {
16094                     final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16095                     updateDigest(digest, new File(pkg.baseCodePath));
16096                     if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16097                         for (String path : pkg.splitCodePaths) {
16098                             updateDigest(digest, new File(path));
16099                         }
16100                     }
16101                     digestBytes = digest.digest();
16102                 } catch (NoSuchAlgorithmException | IOException e) {
16103                     res.setError(INSTALL_FAILED_INVALID_APK,
16104                             "Could not compute hash: " + pkgName);
16105                     return;
16106                 }
16107                 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16108                     res.setError(INSTALL_FAILED_INVALID_APK,
16109                             "New package fails restrict-update check: " + pkgName);
16110                     return;
16111                 }
16112                 // retain upgrade restriction
16113                 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16114             }
16115
16116             // Check for shared user id changes
16117             String invalidPackageName =
16118                     getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16119             if (invalidPackageName != null) {
16120                 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16121                         "Package " + invalidPackageName + " tried to change user "
16122                                 + oldPackage.mSharedUserId);
16123                 return;
16124             }
16125
16126             // In case of rollback, remember per-user/profile install state
16127             allUsers = sUserManager.getUserIds();
16128             installedUsers = ps.queryInstalledUsers(allUsers, true);
16129
16130             // don't allow an upgrade from full to ephemeral
16131             if (isInstantApp) {
16132                 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16133                     for (int currentUser : allUsers) {
16134                         if (!ps.getInstantApp(currentUser)) {
16135                             // can't downgrade from full to instant
16136                             Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16137                                     + " for user: " + currentUser);
16138                             res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16139                             return;
16140                         }
16141                     }
16142                 } else if (!ps.getInstantApp(user.getIdentifier())) {
16143                     // can't downgrade from full to instant
16144                     Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16145                             + " for user: " + user.getIdentifier());
16146                     res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16147                     return;
16148                 }
16149             }
16150         }
16151
16152         // Update what is removed
16153         res.removedInfo = new PackageRemovedInfo(this);
16154         res.removedInfo.uid = oldPackage.applicationInfo.uid;
16155         res.removedInfo.removedPackage = oldPackage.packageName;
16156         res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16157         res.removedInfo.isUpdate = true;
16158         res.removedInfo.origUsers = installedUsers;
16159         final PackageSetting ps = mSettings.getPackageLPr(pkgName);
16160         res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16161         for (int i = 0; i < installedUsers.length; i++) {
16162             final int userId = installedUsers[i];
16163             res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16164         }
16165
16166         final int childCount = (oldPackage.childPackages != null)
16167                 ? oldPackage.childPackages.size() : 0;
16168         for (int i = 0; i < childCount; i++) {
16169             boolean childPackageUpdated = false;
16170             PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16171             final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16172             if (res.addedChildPackages != null) {
16173                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16174                 if (childRes != null) {
16175                     childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16176                     childRes.removedInfo.removedPackage = childPkg.packageName;
16177                     childRes.removedInfo.isUpdate = true;
16178                     childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16179                     childPackageUpdated = true;
16180                 }
16181             }
16182             if (!childPackageUpdated) {
16183                 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16184                 childRemovedRes.removedPackage = childPkg.packageName;
16185                 childRemovedRes.isUpdate = false;
16186                 childRemovedRes.dataRemoved = true;
16187                 synchronized (mPackages) {
16188                     if (childPs != null) {
16189                         childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16190                     }
16191                 }
16192                 if (res.removedInfo.removedChildPackages == null) {
16193                     res.removedInfo.removedChildPackages = new ArrayMap<>();
16194                 }
16195                 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16196             }
16197         }
16198
16199         boolean sysPkg = (isSystemApp(oldPackage));
16200         if (sysPkg) {
16201             // Set the system/privileged flags as needed
16202             final boolean privileged =
16203                     (oldPackage.applicationInfo.privateFlags
16204                             & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16205             final int systemPolicyFlags = policyFlags
16206                     | PackageParser.PARSE_IS_SYSTEM
16207                     | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16208
16209             replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16210                     user, allUsers, installerPackageName, res, installReason);
16211         } else {
16212             replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16213                     user, allUsers, installerPackageName, res, installReason);
16214         }
16215     }
16216
16217     public List<String> getPreviousCodePaths(String packageName) {
16218         final PackageSetting ps = mSettings.mPackages.get(packageName);
16219         final List<String> result = new ArrayList<String>();
16220         if (ps != null && ps.oldCodePaths != null) {
16221             result.addAll(ps.oldCodePaths);
16222         }
16223         return result;
16224     }
16225
16226     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16227             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16228             int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16229             int installReason) {
16230         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16231                 + deletedPackage);
16232
16233         String pkgName = deletedPackage.packageName;
16234         boolean deletedPkg = true;
16235         boolean addedPkg = false;
16236         boolean updatedSettings = false;
16237         final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16238         final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16239                 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16240
16241         final long origUpdateTime = (pkg.mExtras != null)
16242                 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16243
16244         // First delete the existing package while retaining the data directory
16245         if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16246                 res.removedInfo, true, pkg)) {
16247             // If the existing package wasn't successfully deleted
16248             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16249             deletedPkg = false;
16250         } else {
16251             // Successfully deleted the old package; proceed with replace.
16252
16253             // If deleted package lived in a container, give users a chance to
16254             // relinquish resources before killing.
16255             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16256                 if (DEBUG_INSTALL) {
16257                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16258                 }
16259                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16260                 final ArrayList<String> pkgList = new ArrayList<String>(1);
16261                 pkgList.add(deletedPackage.applicationInfo.packageName);
16262                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16263             }
16264
16265             clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16266                     | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16267             clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16268
16269             try {
16270                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
16271                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16272                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16273                         installReason);
16274
16275                 // Update the in-memory copy of the previous code paths.
16276                 PackageSetting ps = mSettings.mPackages.get(pkgName);
16277                 if (!killApp) {
16278                     if (ps.oldCodePaths == null) {
16279                         ps.oldCodePaths = new ArraySet<>();
16280                     }
16281                     Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16282                     if (deletedPackage.splitCodePaths != null) {
16283                         Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16284                     }
16285                 } else {
16286                     ps.oldCodePaths = null;
16287                 }
16288                 if (ps.childPackageNames != null) {
16289                     for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16290                         final String childPkgName = ps.childPackageNames.get(i);
16291                         final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16292                         childPs.oldCodePaths = ps.oldCodePaths;
16293                     }
16294                 }
16295                 // set instant app status, but, only if it's explicitly specified
16296                 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16297                 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16298                 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16299                 prepareAppDataAfterInstallLIF(newPackage);
16300                 addedPkg = true;
16301                 mDexManager.notifyPackageUpdated(newPackage.packageName,
16302                         newPackage.baseCodePath, newPackage.splitCodePaths);
16303             } catch (PackageManagerException e) {
16304                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
16305             }
16306         }
16307
16308         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16309             if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16310
16311             // Revert all internal state mutations and added folders for the failed install
16312             if (addedPkg) {
16313                 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16314                         res.removedInfo, true, null);
16315             }
16316
16317             // Restore the old package
16318             if (deletedPkg) {
16319                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16320                 File restoreFile = new File(deletedPackage.codePath);
16321                 // Parse old package
16322                 boolean oldExternal = isExternal(deletedPackage);
16323                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16324                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16325                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16326                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16327                 try {
16328                     scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16329                             null);
16330                 } catch (PackageManagerException e) {
16331                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16332                             + e.getMessage());
16333                     return;
16334                 }
16335
16336                 synchronized (mPackages) {
16337                     // Ensure the installer package name up to date
16338                     setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16339
16340                     // Update permissions for restored package
16341                     updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16342
16343                     mSettings.writeLPr();
16344                 }
16345
16346                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16347             }
16348         } else {
16349             synchronized (mPackages) {
16350                 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16351                 if (ps != null) {
16352                     res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16353                     if (res.removedInfo.removedChildPackages != null) {
16354                         final int childCount = res.removedInfo.removedChildPackages.size();
16355                         // Iterate in reverse as we may modify the collection
16356                         for (int i = childCount - 1; i >= 0; i--) {
16357                             String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16358                             if (res.addedChildPackages.containsKey(childPackageName)) {
16359                                 res.removedInfo.removedChildPackages.removeAt(i);
16360                             } else {
16361                                 PackageRemovedInfo childInfo = res.removedInfo
16362                                         .removedChildPackages.valueAt(i);
16363                                 childInfo.removedForAllUsers = mPackages.get(
16364                                         childInfo.removedPackage) == null;
16365                             }
16366                         }
16367                     }
16368                 }
16369             }
16370         }
16371     }
16372
16373     private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16374             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16375             int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16376             int installReason) {
16377         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16378                 + ", old=" + deletedPackage);
16379
16380         final boolean disabledSystem;
16381
16382         // Remove existing system package
16383         removePackageLI(deletedPackage, true);
16384
16385         synchronized (mPackages) {
16386             disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16387         }
16388         if (!disabledSystem) {
16389             // We didn't need to disable the .apk as a current system package,
16390             // which means we are replacing another update that is already
16391             // installed.  We need to make sure to delete the older one's .apk.
16392             res.removedInfo.args = createInstallArgsForExisting(0,
16393                     deletedPackage.applicationInfo.getCodePath(),
16394                     deletedPackage.applicationInfo.getResourcePath(),
16395                     getAppDexInstructionSets(deletedPackage.applicationInfo));
16396         } else {
16397             res.removedInfo.args = null;
16398         }
16399
16400         // Successfully disabled the old package. Now proceed with re-installation
16401         clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16402                 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16403         clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16404
16405         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16406         pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16407                 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16408
16409         PackageParser.Package newPackage = null;
16410         try {
16411             // Add the package to the internal data structures
16412             newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16413
16414             // Set the update and install times
16415             PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16416             setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16417                     System.currentTimeMillis());
16418
16419             // Update the package dynamic state if succeeded
16420             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16421                 // Now that the install succeeded make sure we remove data
16422                 // directories for any child package the update removed.
16423                 final int deletedChildCount = (deletedPackage.childPackages != null)
16424                         ? deletedPackage.childPackages.size() : 0;
16425                 final int newChildCount = (newPackage.childPackages != null)
16426                         ? newPackage.childPackages.size() : 0;
16427                 for (int i = 0; i < deletedChildCount; i++) {
16428                     PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16429                     boolean childPackageDeleted = true;
16430                     for (int j = 0; j < newChildCount; j++) {
16431                         PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16432                         if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16433                             childPackageDeleted = false;
16434                             break;
16435                         }
16436                     }
16437                     if (childPackageDeleted) {
16438                         PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16439                                 deletedChildPkg.packageName);
16440                         if (ps != null && res.removedInfo.removedChildPackages != null) {
16441                             PackageRemovedInfo removedChildRes = res.removedInfo
16442                                     .removedChildPackages.get(deletedChildPkg.packageName);
16443                             removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16444                             removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16445                         }
16446                     }
16447                 }
16448
16449                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16450                         installReason);
16451                 prepareAppDataAfterInstallLIF(newPackage);
16452
16453                 mDexManager.notifyPackageUpdated(newPackage.packageName,
16454                             newPackage.baseCodePath, newPackage.splitCodePaths);
16455             }
16456         } catch (PackageManagerException e) {
16457             res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16458             res.setError("Package couldn't be installed in " + pkg.codePath, e);
16459         }
16460
16461         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16462             // Re installation failed. Restore old information
16463             // Remove new pkg information
16464             if (newPackage != null) {
16465                 removeInstalledPackageLI(newPackage, true);
16466             }
16467             // Add back the old system package
16468             try {
16469                 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16470             } catch (PackageManagerException e) {
16471                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16472             }
16473
16474             synchronized (mPackages) {
16475                 if (disabledSystem) {
16476                     enableSystemPackageLPw(deletedPackage);
16477                 }
16478
16479                 // Ensure the installer package name up to date
16480                 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16481
16482                 // Update permissions for restored package
16483                 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16484
16485                 mSettings.writeLPr();
16486             }
16487
16488             Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16489                     + " after failed upgrade");
16490         }
16491     }
16492
16493     /**
16494      * Checks whether the parent or any of the child packages have a change shared
16495      * user. For a package to be a valid update the shred users of the parent and
16496      * the children should match. We may later support changing child shared users.
16497      * @param oldPkg The updated package.
16498      * @param newPkg The update package.
16499      * @return The shared user that change between the versions.
16500      */
16501     private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16502             PackageParser.Package newPkg) {
16503         // Check parent shared user
16504         if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16505             return newPkg.packageName;
16506         }
16507         // Check child shared users
16508         final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16509         final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16510         for (int i = 0; i < newChildCount; i++) {
16511             PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16512             // If this child was present, did it have the same shared user?
16513             for (int j = 0; j < oldChildCount; j++) {
16514                 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16515                 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16516                         && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16517                     return newChildPkg.packageName;
16518                 }
16519             }
16520         }
16521         return null;
16522     }
16523
16524     private void removeNativeBinariesLI(PackageSetting ps) {
16525         // Remove the lib path for the parent package
16526         if (ps != null) {
16527             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16528             // Remove the lib path for the child packages
16529             final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16530             for (int i = 0; i < childCount; i++) {
16531                 PackageSetting childPs = null;
16532                 synchronized (mPackages) {
16533                     childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16534                 }
16535                 if (childPs != null) {
16536                     NativeLibraryHelper.removeNativeBinariesLI(childPs
16537                             .legacyNativeLibraryPathString);
16538                 }
16539             }
16540         }
16541     }
16542
16543     private void enableSystemPackageLPw(PackageParser.Package pkg) {
16544         // Enable the parent package
16545         mSettings.enableSystemPackageLPw(pkg.packageName);
16546         // Enable the child packages
16547         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16548         for (int i = 0; i < childCount; i++) {
16549             PackageParser.Package childPkg = pkg.childPackages.get(i);
16550             mSettings.enableSystemPackageLPw(childPkg.packageName);
16551         }
16552     }
16553
16554     private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16555             PackageParser.Package newPkg) {
16556         // Disable the parent package (parent always replaced)
16557         boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16558         // Disable the child packages
16559         final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16560         for (int i = 0; i < childCount; i++) {
16561             PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16562             final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16563             disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16564         }
16565         return disabled;
16566     }
16567
16568     private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16569             String installerPackageName) {
16570         // Enable the parent package
16571         mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16572         // Enable the child packages
16573         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16574         for (int i = 0; i < childCount; i++) {
16575             PackageParser.Package childPkg = pkg.childPackages.get(i);
16576             mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16577         }
16578     }
16579
16580     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
16581         // Collect all used permissions in the UID
16582         ArraySet<String> usedPermissions = new ArraySet<>();
16583         final int packageCount = su.packages.size();
16584         for (int i = 0; i < packageCount; i++) {
16585             PackageSetting ps = su.packages.valueAt(i);
16586             if (ps.pkg == null) {
16587                 continue;
16588             }
16589             final int requestedPermCount = ps.pkg.requestedPermissions.size();
16590             for (int j = 0; j < requestedPermCount; j++) {
16591                 String permission = ps.pkg.requestedPermissions.get(j);
16592                 BasePermission bp = mSettings.mPermissions.get(permission);
16593                 if (bp != null) {
16594                     usedPermissions.add(permission);
16595                 }
16596             }
16597         }
16598
16599         PermissionsState permissionsState = su.getPermissionsState();
16600         // Prune install permissions
16601         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
16602         final int installPermCount = installPermStates.size();
16603         for (int i = installPermCount - 1; i >= 0;  i--) {
16604             PermissionState permissionState = installPermStates.get(i);
16605             if (!usedPermissions.contains(permissionState.getName())) {
16606                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16607                 if (bp != null) {
16608                     permissionsState.revokeInstallPermission(bp);
16609                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
16610                             PackageManager.MASK_PERMISSION_FLAGS, 0);
16611                 }
16612             }
16613         }
16614
16615         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
16616
16617         // Prune runtime permissions
16618         for (int userId : allUserIds) {
16619             List<PermissionState> runtimePermStates = permissionsState
16620                     .getRuntimePermissionStates(userId);
16621             final int runtimePermCount = runtimePermStates.size();
16622             for (int i = runtimePermCount - 1; i >= 0; i--) {
16623                 PermissionState permissionState = runtimePermStates.get(i);
16624                 if (!usedPermissions.contains(permissionState.getName())) {
16625                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16626                     if (bp != null) {
16627                         permissionsState.revokeRuntimePermission(bp, userId);
16628                         permissionsState.updatePermissionFlags(bp, userId,
16629                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
16630                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
16631                                 runtimePermissionChangedUserIds, userId);
16632                     }
16633                 }
16634             }
16635         }
16636
16637         return runtimePermissionChangedUserIds;
16638     }
16639
16640     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16641             int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16642         // Update the parent package setting
16643         updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16644                 res, user, installReason);
16645         // Update the child packages setting
16646         final int childCount = (newPackage.childPackages != null)
16647                 ? newPackage.childPackages.size() : 0;
16648         for (int i = 0; i < childCount; i++) {
16649             PackageParser.Package childPackage = newPackage.childPackages.get(i);
16650             PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16651             updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16652                     childRes.origUsers, childRes, user, installReason);
16653         }
16654     }
16655
16656     private void updateSettingsInternalLI(PackageParser.Package newPackage,
16657             String installerPackageName, int[] allUsers, int[] installedForUsers,
16658             PackageInstalledInfo res, UserHandle user, int installReason) {
16659         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16660
16661         String pkgName = newPackage.packageName;
16662         synchronized (mPackages) {
16663             //write settings. the installStatus will be incomplete at this stage.
16664             //note that the new package setting would have already been
16665             //added to mPackages. It hasn't been persisted yet.
16666             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16667             // TODO: Remove this write? It's also written at the end of this method
16668             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16669             mSettings.writeLPr();
16670             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16671         }
16672
16673         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
16674         synchronized (mPackages) {
16675             updatePermissionsLPw(newPackage.packageName, newPackage,
16676                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
16677                             ? UPDATE_PERMISSIONS_ALL : 0));
16678             // For system-bundled packages, we assume that installing an upgraded version
16679             // of the package implies that the user actually wants to run that new code,
16680             // so we enable the package.
16681             PackageSetting ps = mSettings.mPackages.get(pkgName);
16682             final int userId = user.getIdentifier();
16683             if (ps != null) {
16684                 if (isSystemApp(newPackage)) {
16685                     if (DEBUG_INSTALL) {
16686                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16687                     }
16688                     // Enable system package for requested users
16689                     if (res.origUsers != null) {
16690                         for (int origUserId : res.origUsers) {
16691                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
16692                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16693                                         origUserId, installerPackageName);
16694                             }
16695                         }
16696                     }
16697                     // Also convey the prior install/uninstall state
16698                     if (allUsers != null && installedForUsers != null) {
16699                         for (int currentUserId : allUsers) {
16700                             final boolean installed = ArrayUtils.contains(
16701                                     installedForUsers, currentUserId);
16702                             if (DEBUG_INSTALL) {
16703                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16704                             }
16705                             ps.setInstalled(installed, currentUserId);
16706                         }
16707                         // these install state changes will be persisted in the
16708                         // upcoming call to mSettings.writeLPr().
16709                     }
16710                 }
16711                 // It's implied that when a user requests installation, they want the app to be
16712                 // installed and enabled.
16713                 if (userId != UserHandle.USER_ALL) {
16714                     ps.setInstalled(true, userId);
16715                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16716                 }
16717
16718                 // When replacing an existing package, preserve the original install reason for all
16719                 // users that had the package installed before.
16720                 final Set<Integer> previousUserIds = new ArraySet<>();
16721                 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16722                     final int installReasonCount = res.removedInfo.installReasons.size();
16723                     for (int i = 0; i < installReasonCount; i++) {
16724                         final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16725                         final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16726                         ps.setInstallReason(previousInstallReason, previousUserId);
16727                         previousUserIds.add(previousUserId);
16728                     }
16729                 }
16730
16731                 // Set install reason for users that are having the package newly installed.
16732                 if (userId == UserHandle.USER_ALL) {
16733                     for (int currentUserId : sUserManager.getUserIds()) {
16734                         if (!previousUserIds.contains(currentUserId)) {
16735                             ps.setInstallReason(installReason, currentUserId);
16736                         }
16737                     }
16738                 } else if (!previousUserIds.contains(userId)) {
16739                     ps.setInstallReason(installReason, userId);
16740                 }
16741                 mSettings.writeKernelMappingLPr(ps);
16742             }
16743             res.name = pkgName;
16744             res.uid = newPackage.applicationInfo.uid;
16745             res.pkg = newPackage;
16746             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16747             mSettings.setInstallerPackageName(pkgName, installerPackageName);
16748             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16749             //to update install status
16750             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16751             mSettings.writeLPr();
16752             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16753         }
16754
16755         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16756     }
16757
16758     private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16759         try {
16760             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16761             installPackageLI(args, res);
16762         } finally {
16763             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16764         }
16765     }
16766
16767     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16768         final int installFlags = args.installFlags;
16769         final String installerPackageName = args.installerPackageName;
16770         final String volumeUuid = args.volumeUuid;
16771         final File tmpPackageFile = new File(args.getCodePath());
16772         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16773         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16774                 || (args.volumeUuid != null));
16775         final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16776         final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16777         final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16778         boolean replace = false;
16779         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16780         if (args.move != null) {
16781             // moving a complete application; perform an initial scan on the new install location
16782             scanFlags |= SCAN_INITIAL;
16783         }
16784         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16785             scanFlags |= SCAN_DONT_KILL_APP;
16786         }
16787         if (instantApp) {
16788             scanFlags |= SCAN_AS_INSTANT_APP;
16789         }
16790         if (fullApp) {
16791             scanFlags |= SCAN_AS_FULL_APP;
16792         }
16793
16794         // Result object to be returned
16795         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16796
16797         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16798
16799         // Sanity check
16800         if (instantApp && (forwardLocked || onExternal)) {
16801             Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16802                     + " external=" + onExternal);
16803             res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16804             return;
16805         }
16806
16807         // Retrieve PackageSettings and parse package
16808         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16809                 | PackageParser.PARSE_ENFORCE_CODE
16810                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16811                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16812                 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16813                 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16814         PackageParser pp = new PackageParser();
16815         pp.setSeparateProcesses(mSeparateProcesses);
16816         pp.setDisplayMetrics(mMetrics);
16817         pp.setCallback(mPackageParserCallback);
16818
16819         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16820         final PackageParser.Package pkg;
16821         try {
16822             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16823         } catch (PackageParserException e) {
16824             res.setError("Failed parse during installPackageLI", e);
16825             return;
16826         } finally {
16827             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16828         }
16829
16830         // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16831         if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16832             Slog.w(TAG, "Instant app package " + pkg.packageName
16833                     + " does not target O, this will be a fatal error.");
16834             // STOPSHIP: Make this a fatal error
16835             pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
16836         }
16837         if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16838             Slog.w(TAG, "Instant app package " + pkg.packageName
16839                     + " does not target targetSandboxVersion 2, this will be a fatal error.");
16840             // STOPSHIP: Make this a fatal error
16841             pkg.applicationInfo.targetSandboxVersion = 2;
16842         }
16843
16844         if (pkg.applicationInfo.isStaticSharedLibrary()) {
16845             // Static shared libraries have synthetic package names
16846             renameStaticSharedLibraryPackage(pkg);
16847
16848             // No static shared libs on external storage
16849             if (onExternal) {
16850                 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16851                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16852                         "Packages declaring static-shared libs cannot be updated");
16853                 return;
16854             }
16855         }
16856
16857         // If we are installing a clustered package add results for the children
16858         if (pkg.childPackages != null) {
16859             synchronized (mPackages) {
16860                 final int childCount = pkg.childPackages.size();
16861                 for (int i = 0; i < childCount; i++) {
16862                     PackageParser.Package childPkg = pkg.childPackages.get(i);
16863                     PackageInstalledInfo childRes = new PackageInstalledInfo();
16864                     childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16865                     childRes.pkg = childPkg;
16866                     childRes.name = childPkg.packageName;
16867                     PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16868                     if (childPs != null) {
16869                         childRes.origUsers = childPs.queryInstalledUsers(
16870                                 sUserManager.getUserIds(), true);
16871                     }
16872                     if ((mPackages.containsKey(childPkg.packageName))) {
16873                         childRes.removedInfo = new PackageRemovedInfo(this);
16874                         childRes.removedInfo.removedPackage = childPkg.packageName;
16875                     }
16876                     if (res.addedChildPackages == null) {
16877                         res.addedChildPackages = new ArrayMap<>();
16878                     }
16879                     res.addedChildPackages.put(childPkg.packageName, childRes);
16880                 }
16881             }
16882         }
16883
16884         // If package doesn't declare API override, mark that we have an install
16885         // time CPU ABI override.
16886         if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16887             pkg.cpuAbiOverride = args.abiOverride;
16888         }
16889
16890         String pkgName = res.name = pkg.packageName;
16891         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16892             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16893                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16894                 return;
16895             }
16896         }
16897
16898         try {
16899             // either use what we've been given or parse directly from the APK
16900             if (args.certificates != null) {
16901                 try {
16902                     PackageParser.populateCertificates(pkg, args.certificates);
16903                 } catch (PackageParserException e) {
16904                     // there was something wrong with the certificates we were given;
16905                     // try to pull them from the APK
16906                     PackageParser.collectCertificates(pkg, parseFlags);
16907                 }
16908             } else {
16909                 PackageParser.collectCertificates(pkg, parseFlags);
16910             }
16911         } catch (PackageParserException e) {
16912             res.setError("Failed collect during installPackageLI", e);
16913             return;
16914         }
16915
16916         // Get rid of all references to package scan path via parser.
16917         pp = null;
16918         String oldCodePath = null;
16919         boolean systemApp = false;
16920         synchronized (mPackages) {
16921             // Check if installing already existing package
16922             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16923                 String oldName = mSettings.getRenamedPackageLPr(pkgName);
16924                 if (pkg.mOriginalPackages != null
16925                         && pkg.mOriginalPackages.contains(oldName)
16926                         && mPackages.containsKey(oldName)) {
16927                     // This package is derived from an original package,
16928                     // and this device has been updating from that original
16929                     // name.  We must continue using the original name, so
16930                     // rename the new package here.
16931                     pkg.setPackageName(oldName);
16932                     pkgName = pkg.packageName;
16933                     replace = true;
16934                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16935                             + oldName + " pkgName=" + pkgName);
16936                 } else if (mPackages.containsKey(pkgName)) {
16937                     // This package, under its official name, already exists
16938                     // on the device; we should replace it.
16939                     replace = true;
16940                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16941                 }
16942
16943                 // Child packages are installed through the parent package
16944                 if (pkg.parentPackage != null) {
16945                     res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16946                             "Package " + pkg.packageName + " is child of package "
16947                                     + pkg.parentPackage.parentPackage + ". Child packages "
16948                                     + "can be updated only through the parent package.");
16949                     return;
16950                 }
16951
16952                 if (replace) {
16953                     // Prevent apps opting out from runtime permissions
16954                     PackageParser.Package oldPackage = mPackages.get(pkgName);
16955                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16956                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16957                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16958                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16959                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16960                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16961                                         + " doesn't support runtime permissions but the old"
16962                                         + " target SDK " + oldTargetSdk + " does.");
16963                         return;
16964                     }
16965                     // Prevent apps from downgrading their targetSandbox.
16966                     final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16967                     final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16968                     if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16969                         res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16970                                 "Package " + pkg.packageName + " new target sandbox "
16971                                 + newTargetSandbox + " is incompatible with the previous value of"
16972                                 + oldTargetSandbox + ".");
16973                         return;
16974                     }
16975
16976                     // Prevent installing of child packages
16977                     if (oldPackage.parentPackage != null) {
16978                         res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16979                                 "Package " + pkg.packageName + " is child of package "
16980                                         + oldPackage.parentPackage + ". Child packages "
16981                                         + "can be updated only through the parent package.");
16982                         return;
16983                     }
16984                 }
16985             }
16986
16987             PackageSetting ps = mSettings.mPackages.get(pkgName);
16988             if (ps != null) {
16989                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16990
16991                 // Static shared libs have same package with different versions where
16992                 // we internally use a synthetic package name to allow multiple versions
16993                 // of the same package, therefore we need to compare signatures against
16994                 // the package setting for the latest library version.
16995                 PackageSetting signatureCheckPs = ps;
16996                 if (pkg.applicationInfo.isStaticSharedLibrary()) {
16997                     SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16998                     if (libraryEntry != null) {
16999                         signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17000                     }
17001                 }
17002
17003                 // Quick sanity check that we're signed correctly if updating;
17004                 // we'll check this again later when scanning, but we want to
17005                 // bail early here before tripping over redefined permissions.
17006                 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17007                     if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17008                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17009                                 + pkg.packageName + " upgrade keys do not match the "
17010                                 + "previously installed version");
17011                         return;
17012                     }
17013                 } else {
17014                     try {
17015                         verifySignaturesLP(signatureCheckPs, pkg);
17016                     } catch (PackageManagerException e) {
17017                         res.setError(e.error, e.getMessage());
17018                         return;
17019                     }
17020                 }
17021
17022                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17023                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17024                     systemApp = (ps.pkg.applicationInfo.flags &
17025                             ApplicationInfo.FLAG_SYSTEM) != 0;
17026                 }
17027                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17028             }
17029
17030             int N = pkg.permissions.size();
17031             for (int i = N-1; i >= 0; i--) {
17032                 PackageParser.Permission perm = pkg.permissions.get(i);
17033                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17034
17035                 // Don't allow anyone but the platform to define ephemeral permissions.
17036                 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17037                         && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17038                     Slog.w(TAG, "Package " + pkg.packageName
17039                             + " attempting to delcare ephemeral permission "
17040                             + perm.info.name + "; Removing ephemeral.");
17041                     perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17042                 }
17043                 // Check whether the newly-scanned package wants to define an already-defined perm
17044                 if (bp != null) {
17045                     // If the defining package is signed with our cert, it's okay.  This
17046                     // also includes the "updating the same package" case, of course.
17047                     // "updating same package" could also involve key-rotation.
17048                     final boolean sigsOk;
17049                     if (bp.sourcePackage.equals(pkg.packageName)
17050                             && (bp.packageSetting instanceof PackageSetting)
17051                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17052                                     scanFlags))) {
17053                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17054                     } else {
17055                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17056                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17057                     }
17058                     if (!sigsOk) {
17059                         // If the owning package is the system itself, we log but allow
17060                         // install to proceed; we fail the install on all other permission
17061                         // redefinitions.
17062                         if (!bp.sourcePackage.equals("android")) {
17063                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17064                                     + pkg.packageName + " attempting to redeclare permission "
17065                                     + perm.info.name + " already owned by " + bp.sourcePackage);
17066                             res.origPermission = perm.info.name;
17067                             res.origPackage = bp.sourcePackage;
17068                             return;
17069                         } else {
17070                             Slog.w(TAG, "Package " + pkg.packageName
17071                                     + " attempting to redeclare system permission "
17072                                     + perm.info.name + "; ignoring new declaration");
17073                             pkg.permissions.remove(i);
17074                         }
17075                     } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17076                         // Prevent apps to change protection level to dangerous from any other
17077                         // type as this would allow a privilege escalation where an app adds a
17078                         // normal/signature permission in other app's group and later redefines
17079                         // it as dangerous leading to the group auto-grant.
17080                         if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17081                                 == PermissionInfo.PROTECTION_DANGEROUS) {
17082                             if (bp != null && !bp.isRuntime()) {
17083                                 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17084                                         + "non-runtime permission " + perm.info.name
17085                                         + " to runtime; keeping old protection level");
17086                                 perm.info.protectionLevel = bp.protectionLevel;
17087                             }
17088                         }
17089                     }
17090                 }
17091             }
17092         }
17093
17094         if (systemApp) {
17095             if (onExternal) {
17096                 // Abort update; system app can't be replaced with app on sdcard
17097                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17098                         "Cannot install updates to system apps on sdcard");
17099                 return;
17100             } else if (instantApp) {
17101                 // Abort update; system app can't be replaced with an instant app
17102                 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17103                         "Cannot update a system app with an instant app");
17104                 return;
17105             }
17106         }
17107
17108         if (args.move != null) {
17109             // We did an in-place move, so dex is ready to roll
17110             scanFlags |= SCAN_NO_DEX;
17111             scanFlags |= SCAN_MOVE;
17112
17113             synchronized (mPackages) {
17114                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17115                 if (ps == null) {
17116                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17117                             "Missing settings for moved package " + pkgName);
17118                 }
17119
17120                 // We moved the entire application as-is, so bring over the
17121                 // previously derived ABI information.
17122                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17123                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17124             }
17125
17126         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17127             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17128             scanFlags |= SCAN_NO_DEX;
17129
17130             try {
17131                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17132                     args.abiOverride : pkg.cpuAbiOverride);
17133                 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17134                         true /*extractLibs*/, mAppLib32InstallDir);
17135             } catch (PackageManagerException pme) {
17136                 Slog.e(TAG, "Error deriving application ABI", pme);
17137                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17138                 return;
17139             }
17140
17141             // Shared libraries for the package need to be updated.
17142             synchronized (mPackages) {
17143                 try {
17144                     updateSharedLibrariesLPr(pkg, null);
17145                 } catch (PackageManagerException e) {
17146                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17147                 }
17148             }
17149
17150             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17151             // Do not run PackageDexOptimizer through the local performDexOpt
17152             // method because `pkg` may not be in `mPackages` yet.
17153             //
17154             // Also, don't fail application installs if the dexopt step fails.
17155             mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17156                     null /* instructionSets */, false /* checkProfiles */,
17157                     getCompilerFilterForReason(REASON_INSTALL),
17158                     getOrCreateCompilerPackageStats(pkg),
17159                     mDexManager.isUsedByOtherApps(pkg.packageName));
17160             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17161
17162             // Notify BackgroundDexOptService that the package has been changed.
17163             // If this is an update of a package which used to fail to compile,
17164             // BDOS will remove it from its blacklist.
17165             // TODO: Layering violation
17166             BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17167         }
17168
17169         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17170             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17171             return;
17172         }
17173
17174         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17175
17176         try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17177                 "installPackageLI")) {
17178             if (replace) {
17179                 if (pkg.applicationInfo.isStaticSharedLibrary()) {
17180                     // Static libs have a synthetic package name containing the version
17181                     // and cannot be updated as an update would get a new package name,
17182                     // unless this is the exact same version code which is useful for
17183                     // development.
17184                     PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17185                     if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17186                         res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17187                                 + "static-shared libs cannot be updated");
17188                         return;
17189                     }
17190                 }
17191                 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17192                         installerPackageName, res, args.installReason);
17193             } else {
17194                 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17195                         args.user, installerPackageName, volumeUuid, res, args.installReason);
17196             }
17197         }
17198
17199         synchronized (mPackages) {
17200             final PackageSetting ps = mSettings.mPackages.get(pkgName);
17201             if (ps != null) {
17202                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17203                 ps.setUpdateAvailable(false /*updateAvailable*/);
17204             }
17205
17206             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17207             for (int i = 0; i < childCount; i++) {
17208                 PackageParser.Package childPkg = pkg.childPackages.get(i);
17209                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17210                 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17211                 if (childPs != null) {
17212                     childRes.newUsers = childPs.queryInstalledUsers(
17213                             sUserManager.getUserIds(), true);
17214                 }
17215             }
17216
17217             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17218                 updateSequenceNumberLP(pkgName, res.newUsers);
17219                 updateInstantAppInstallerLocked(pkgName);
17220             }
17221         }
17222     }
17223
17224     private void startIntentFilterVerifications(int userId, boolean replacing,
17225             PackageParser.Package pkg) {
17226         if (mIntentFilterVerifierComponent == null) {
17227             Slog.w(TAG, "No IntentFilter verification will not be done as "
17228                     + "there is no IntentFilterVerifier available!");
17229             return;
17230         }
17231
17232         final int verifierUid = getPackageUid(
17233                 mIntentFilterVerifierComponent.getPackageName(),
17234                 MATCH_DEBUG_TRIAGED_MISSING,
17235                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17236
17237         Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17238         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17239         mHandler.sendMessage(msg);
17240
17241         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17242         for (int i = 0; i < childCount; i++) {
17243             PackageParser.Package childPkg = pkg.childPackages.get(i);
17244             msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17245             msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17246             mHandler.sendMessage(msg);
17247         }
17248     }
17249
17250     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17251             PackageParser.Package pkg) {
17252         int size = pkg.activities.size();
17253         if (size == 0) {
17254             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17255                     "No activity, so no need to verify any IntentFilter!");
17256             return;
17257         }
17258
17259         final boolean hasDomainURLs = hasDomainURLs(pkg);
17260         if (!hasDomainURLs) {
17261             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17262                     "No domain URLs, so no need to verify any IntentFilter!");
17263             return;
17264         }
17265
17266         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17267                 + " if any IntentFilter from the " + size
17268                 + " Activities needs verification ...");
17269
17270         int count = 0;
17271         final String packageName = pkg.packageName;
17272
17273         synchronized (mPackages) {
17274             // If this is a new install and we see that we've already run verification for this
17275             // package, we have nothing to do: it means the state was restored from backup.
17276             if (!replacing) {
17277                 IntentFilterVerificationInfo ivi =
17278                         mSettings.getIntentFilterVerificationLPr(packageName);
17279                 if (ivi != null) {
17280                     if (DEBUG_DOMAIN_VERIFICATION) {
17281                         Slog.i(TAG, "Package " + packageName+ " already verified: status="
17282                                 + ivi.getStatusString());
17283                     }
17284                     return;
17285                 }
17286             }
17287
17288             // If any filters need to be verified, then all need to be.
17289             boolean needToVerify = false;
17290             for (PackageParser.Activity a : pkg.activities) {
17291                 for (ActivityIntentInfo filter : a.intents) {
17292                     if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17293                         if (DEBUG_DOMAIN_VERIFICATION) {
17294                             Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17295                         }
17296                         needToVerify = true;
17297                         break;
17298                     }
17299                 }
17300             }
17301
17302             if (needToVerify) {
17303                 final int verificationId = mIntentFilterVerificationToken++;
17304                 for (PackageParser.Activity a : pkg.activities) {
17305                     for (ActivityIntentInfo filter : a.intents) {
17306                         if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17307                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17308                                     "Verification needed for IntentFilter:" + filter.toString());
17309                             mIntentFilterVerifier.addOneIntentFilterVerification(
17310                                     verifierUid, userId, verificationId, filter, packageName);
17311                             count++;
17312                         }
17313                     }
17314                 }
17315             }
17316         }
17317
17318         if (count > 0) {
17319             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17320                     + " IntentFilter verification" + (count > 1 ? "s" : "")
17321                     +  " for userId:" + userId);
17322             mIntentFilterVerifier.startVerifications(userId);
17323         } else {
17324             if (DEBUG_DOMAIN_VERIFICATION) {
17325                 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17326             }
17327         }
17328     }
17329
17330     private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17331         final ComponentName cn  = filter.activity.getComponentName();
17332         final String packageName = cn.getPackageName();
17333
17334         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17335                 packageName);
17336         if (ivi == null) {
17337             return true;
17338         }
17339         int status = ivi.getStatus();
17340         switch (status) {
17341             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17342             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17343                 return true;
17344
17345             default:
17346                 // Nothing to do
17347                 return false;
17348         }
17349     }
17350
17351     private static boolean isMultiArch(ApplicationInfo info) {
17352         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17353     }
17354
17355     private static boolean isExternal(PackageParser.Package pkg) {
17356         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17357     }
17358
17359     private static boolean isExternal(PackageSetting ps) {
17360         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17361     }
17362
17363     private static boolean isSystemApp(PackageParser.Package pkg) {
17364         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17365     }
17366
17367     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17368         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17369     }
17370
17371     private static boolean hasDomainURLs(PackageParser.Package pkg) {
17372         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17373     }
17374
17375     private static boolean isSystemApp(PackageSetting ps) {
17376         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17377     }
17378
17379     private static boolean isUpdatedSystemApp(PackageSetting ps) {
17380         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17381     }
17382
17383     private int packageFlagsToInstallFlags(PackageSetting ps) {
17384         int installFlags = 0;
17385         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17386             // This existing package was an external ASEC install when we have
17387             // the external flag without a UUID
17388             installFlags |= PackageManager.INSTALL_EXTERNAL;
17389         }
17390         if (ps.isForwardLocked()) {
17391             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17392         }
17393         return installFlags;
17394     }
17395
17396     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17397         if (isExternal(pkg)) {
17398             if (TextUtils.isEmpty(pkg.volumeUuid)) {
17399                 return StorageManager.UUID_PRIMARY_PHYSICAL;
17400             } else {
17401                 return pkg.volumeUuid;
17402             }
17403         } else {
17404             return StorageManager.UUID_PRIVATE_INTERNAL;
17405         }
17406     }
17407
17408     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17409         if (isExternal(pkg)) {
17410             if (TextUtils.isEmpty(pkg.volumeUuid)) {
17411                 return mSettings.getExternalVersion();
17412             } else {
17413                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
17414             }
17415         } else {
17416             return mSettings.getInternalVersion();
17417         }
17418     }
17419
17420     private void deleteTempPackageFiles() {
17421         final FilenameFilter filter = new FilenameFilter() {
17422             public boolean accept(File dir, String name) {
17423                 return name.startsWith("vmdl") && name.endsWith(".tmp");
17424             }
17425         };
17426         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17427             file.delete();
17428         }
17429     }
17430
17431     @Override
17432     public void deletePackageAsUser(String packageName, int versionCode,
17433             IPackageDeleteObserver observer, int userId, int flags) {
17434         deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17435                 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17436     }
17437
17438     @Override
17439     public void deletePackageVersioned(VersionedPackage versionedPackage,
17440             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17441         mContext.enforceCallingOrSelfPermission(
17442                 android.Manifest.permission.DELETE_PACKAGES, null);
17443         Preconditions.checkNotNull(versionedPackage);
17444         Preconditions.checkNotNull(observer);
17445         Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17446                 PackageManager.VERSION_CODE_HIGHEST,
17447                 Integer.MAX_VALUE, "versionCode must be >= -1");
17448
17449         final String packageName = versionedPackage.getPackageName();
17450         // TODO: We will change version code to long, so in the new API it is long
17451         final int versionCode = (int) versionedPackage.getVersionCode();
17452         final String internalPackageName;
17453         synchronized (mPackages) {
17454             // Normalize package name to handle renamed packages and static libs
17455             internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17456                     // TODO: We will change version code to long, so in the new API it is long
17457                     (int) versionedPackage.getVersionCode());
17458         }
17459
17460         final int uid = Binder.getCallingUid();
17461         if (!isOrphaned(internalPackageName)
17462                 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17463             try {
17464                 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17465                 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17466                 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17467                 observer.onUserActionRequired(intent);
17468             } catch (RemoteException re) {
17469             }
17470             return;
17471         }
17472         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17473         final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17474         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17475             mContext.enforceCallingOrSelfPermission(
17476                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17477                     "deletePackage for user " + userId);
17478         }
17479
17480         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17481             try {
17482                 observer.onPackageDeleted(packageName,
17483                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17484             } catch (RemoteException re) {
17485             }
17486             return;
17487         }
17488
17489         if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17490             try {
17491                 observer.onPackageDeleted(packageName,
17492                         PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17493             } catch (RemoteException re) {
17494             }
17495             return;
17496         }
17497
17498         if (DEBUG_REMOVE) {
17499             Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17500                     + " deleteAllUsers: " + deleteAllUsers + " version="
17501                     + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17502                     ? "VERSION_CODE_HIGHEST" : versionCode));
17503         }
17504         // Queue up an async operation since the package deletion may take a little while.
17505         mHandler.post(new Runnable() {
17506             public void run() {
17507                 mHandler.removeCallbacks(this);
17508                 int returnCode;
17509                 if (!deleteAllUsers) {
17510                     returnCode = deletePackageX(internalPackageName, versionCode,
17511                             userId, deleteFlags);
17512                 } else {
17513                     int[] blockUninstallUserIds = getBlockUninstallForUsers(
17514                             internalPackageName, users);
17515                     // If nobody is blocking uninstall, proceed with delete for all users
17516                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17517                         returnCode = deletePackageX(internalPackageName, versionCode,
17518                                 userId, deleteFlags);
17519                     } else {
17520                         // Otherwise uninstall individually for users with blockUninstalls=false
17521                         final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17522                         for (int userId : users) {
17523                             if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17524                                 returnCode = deletePackageX(internalPackageName, versionCode,
17525                                         userId, userFlags);
17526                                 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17527                                     Slog.w(TAG, "Package delete failed for user " + userId
17528                                             + ", returnCode " + returnCode);
17529                                 }
17530                             }
17531                         }
17532                         // The app has only been marked uninstalled for certain users.
17533                         // We still need to report that delete was blocked
17534                         returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17535                     }
17536                 }
17537                 try {
17538                     observer.onPackageDeleted(packageName, returnCode, null);
17539                 } catch (RemoteException e) {
17540                     Log.i(TAG, "Observer no longer exists.");
17541                 } //end catch
17542             } //end run
17543         });
17544     }
17545
17546     private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17547         if (pkg.staticSharedLibName != null) {
17548             return pkg.manifestPackageName;
17549         }
17550         return pkg.packageName;
17551     }
17552
17553     private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17554         // Handle renamed packages
17555         String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17556         packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17557
17558         // Is this a static library?
17559         SparseArray<SharedLibraryEntry> versionedLib =
17560                 mStaticLibsByDeclaringPackage.get(packageName);
17561         if (versionedLib == null || versionedLib.size() <= 0) {
17562             return packageName;
17563         }
17564
17565         // Figure out which lib versions the caller can see
17566         SparseIntArray versionsCallerCanSee = null;
17567         final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17568         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17569                 && callingAppId != Process.ROOT_UID) {
17570             versionsCallerCanSee = new SparseIntArray();
17571             String libName = versionedLib.valueAt(0).info.getName();
17572             String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17573             if (uidPackages != null) {
17574                 for (String uidPackage : uidPackages) {
17575                     PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17576                     final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17577                     if (libIdx >= 0) {
17578                         final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
17579                         versionsCallerCanSee.append(libVersion, libVersion);
17580                     }
17581                 }
17582             }
17583         }
17584
17585         // Caller can see nothing - done
17586         if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17587             return packageName;
17588         }
17589
17590         // Find the version the caller can see and the app version code
17591         SharedLibraryEntry highestVersion = null;
17592         final int versionCount = versionedLib.size();
17593         for (int i = 0; i < versionCount; i++) {
17594             SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17595             if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17596                     libEntry.info.getVersion()) < 0) {
17597                 continue;
17598             }
17599             // TODO: We will change version code to long, so in the new API it is long
17600             final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode();
17601             if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17602                 if (libVersionCode == versionCode) {
17603                     return libEntry.apk;
17604                 }
17605             } else if (highestVersion == null) {
17606                 highestVersion = libEntry;
17607             } else if (libVersionCode  > highestVersion.info
17608                     .getDeclaringPackage().getVersionCode()) {
17609                 highestVersion = libEntry;
17610             }
17611         }
17612
17613         if (highestVersion != null) {
17614             return highestVersion.apk;
17615         }
17616
17617         return packageName;
17618     }
17619
17620     private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17621         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17622               || callingUid == Process.SYSTEM_UID) {
17623             return true;
17624         }
17625         final int callingUserId = UserHandle.getUserId(callingUid);
17626         // If the caller installed the pkgName, then allow it to silently uninstall.
17627         if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17628             return true;
17629         }
17630
17631         // Allow package verifier to silently uninstall.
17632         if (mRequiredVerifierPackage != null &&
17633                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17634             return true;
17635         }
17636
17637         // Allow package uninstaller to silently uninstall.
17638         if (mRequiredUninstallerPackage != null &&
17639                 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17640             return true;
17641         }
17642
17643         // Allow storage manager to silently uninstall.
17644         if (mStorageManagerPackage != null &&
17645                 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17646             return true;
17647         }
17648         return false;
17649     }
17650
17651     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17652         int[] result = EMPTY_INT_ARRAY;
17653         for (int userId : userIds) {
17654             if (getBlockUninstallForUser(packageName, userId)) {
17655                 result = ArrayUtils.appendInt(result, userId);
17656             }
17657         }
17658         return result;
17659     }
17660
17661     @Override
17662     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17663         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17664     }
17665
17666     private boolean isPackageDeviceAdmin(String packageName, int userId) {
17667         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17668                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17669         try {
17670             if (dpm != null) {
17671                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17672                         /* callingUserOnly =*/ false);
17673                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17674                         : deviceOwnerComponentName.getPackageName();
17675                 // Does the package contains the device owner?
17676                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17677                 // this check is probably not needed, since DO should be registered as a device
17678                 // admin on some user too. (Original bug for this: b/17657954)
17679                 if (packageName.equals(deviceOwnerPackageName)) {
17680                     return true;
17681                 }
17682                 // Does it contain a device admin for any user?
17683                 int[] users;
17684                 if (userId == UserHandle.USER_ALL) {
17685                     users = sUserManager.getUserIds();
17686                 } else {
17687                     users = new int[]{userId};
17688                 }
17689                 for (int i = 0; i < users.length; ++i) {
17690                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17691                         return true;
17692                     }
17693                 }
17694             }
17695         } catch (RemoteException e) {
17696         }
17697         return false;
17698     }
17699
17700     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17701         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17702     }
17703
17704     /**
17705      *  This method is an internal method that could be get invoked either
17706      *  to delete an installed package or to clean up a failed installation.
17707      *  After deleting an installed package, a broadcast is sent to notify any
17708      *  listeners that the package has been removed. For cleaning up a failed
17709      *  installation, the broadcast is not necessary since the package's
17710      *  installation wouldn't have sent the initial broadcast either
17711      *  The key steps in deleting a package are
17712      *  deleting the package information in internal structures like mPackages,
17713      *  deleting the packages base directories through installd
17714      *  updating mSettings to reflect current status
17715      *  persisting settings for later use
17716      *  sending a broadcast if necessary
17717      */
17718     private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
17719         final PackageRemovedInfo info = new PackageRemovedInfo(this);
17720         final boolean res;
17721
17722         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17723                 ? UserHandle.USER_ALL : userId;
17724
17725         if (isPackageDeviceAdmin(packageName, removeUser)) {
17726             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17727             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17728         }
17729
17730         PackageSetting uninstalledPs = null;
17731         PackageParser.Package pkg = null;
17732
17733         // for the uninstall-updates case and restricted profiles, remember the per-
17734         // user handle installed state
17735         int[] allUsers;
17736         synchronized (mPackages) {
17737             uninstalledPs = mSettings.mPackages.get(packageName);
17738             if (uninstalledPs == null) {
17739                 Slog.w(TAG, "Not removing non-existent package " + packageName);
17740                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17741             }
17742
17743             if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17744                     && uninstalledPs.versionCode != versionCode) {
17745                 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17746                         + uninstalledPs.versionCode + " != " + versionCode);
17747                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17748             }
17749
17750             // Static shared libs can be declared by any package, so let us not
17751             // allow removing a package if it provides a lib others depend on.
17752             pkg = mPackages.get(packageName);
17753             if (pkg != null && pkg.staticSharedLibName != null) {
17754                 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17755                         pkg.staticSharedLibVersion);
17756                 if (libEntry != null) {
17757                     List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17758                             libEntry.info, 0, userId);
17759                     if (!ArrayUtils.isEmpty(libClientPackages)) {
17760                         Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17761                                 + " hosting lib " + libEntry.info.getName() + " version "
17762                                 + libEntry.info.getVersion()  + " used by " + libClientPackages);
17763                         return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17764                     }
17765                 }
17766             }
17767
17768             allUsers = sUserManager.getUserIds();
17769             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17770         }
17771
17772         final int freezeUser;
17773         if (isUpdatedSystemApp(uninstalledPs)
17774                 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17775             // We're downgrading a system app, which will apply to all users, so
17776             // freeze them all during the downgrade
17777             freezeUser = UserHandle.USER_ALL;
17778         } else {
17779             freezeUser = removeUser;
17780         }
17781
17782         synchronized (mInstallLock) {
17783             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17784             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17785                     deleteFlags, "deletePackageX")) {
17786                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17787                         deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
17788             }
17789             synchronized (mPackages) {
17790                 if (res) {
17791                     if (pkg != null) {
17792                         mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17793                     }
17794                     updateSequenceNumberLP(packageName, info.removedUsers);
17795                     updateInstantAppInstallerLocked(packageName);
17796                 }
17797             }
17798         }
17799
17800         if (res) {
17801             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17802             info.sendPackageRemovedBroadcasts(killApp);
17803             info.sendSystemPackageUpdatedBroadcasts();
17804             info.sendSystemPackageAppearedBroadcasts();
17805         }
17806         // Force a gc here.
17807         Runtime.getRuntime().gc();
17808         // Delete the resources here after sending the broadcast to let
17809         // other processes clean up before deleting resources.
17810         if (info.args != null) {
17811             synchronized (mInstallLock) {
17812                 info.args.doPostDeleteLI(true);
17813             }
17814         }
17815
17816         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17817     }
17818
17819     static class PackageRemovedInfo {
17820         final PackageSender packageSender;
17821         String removedPackage;
17822         int uid = -1;
17823         int removedAppId = -1;
17824         int[] origUsers;
17825         int[] removedUsers = null;
17826         int[] broadcastUsers = null;
17827         SparseArray<Integer> installReasons;
17828         boolean isRemovedPackageSystemUpdate = false;
17829         boolean isUpdate;
17830         boolean dataRemoved;
17831         boolean removedForAllUsers;
17832         boolean isStaticSharedLib;
17833         // Clean up resources deleted packages.
17834         InstallArgs args = null;
17835         ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17836         ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17837
17838         PackageRemovedInfo(PackageSender packageSender) {
17839             this.packageSender = packageSender;
17840         }
17841
17842         void sendPackageRemovedBroadcasts(boolean killApp) {
17843             sendPackageRemovedBroadcastInternal(killApp);
17844             final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17845             for (int i = 0; i < childCount; i++) {
17846                 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17847                 childInfo.sendPackageRemovedBroadcastInternal(killApp);
17848             }
17849         }
17850
17851         void sendSystemPackageUpdatedBroadcasts() {
17852             if (isRemovedPackageSystemUpdate) {
17853                 sendSystemPackageUpdatedBroadcastsInternal();
17854                 final int childCount = (removedChildPackages != null)
17855                         ? removedChildPackages.size() : 0;
17856                 for (int i = 0; i < childCount; i++) {
17857                     PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17858                     if (childInfo.isRemovedPackageSystemUpdate) {
17859                         childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17860                     }
17861                 }
17862             }
17863         }
17864
17865         void sendSystemPackageAppearedBroadcasts() {
17866             final int packageCount = (appearedChildPackages != null)
17867                     ? appearedChildPackages.size() : 0;
17868             for (int i = 0; i < packageCount; i++) {
17869                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17870                 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17871                     true, UserHandle.getAppId(installedInfo.uid),
17872                     installedInfo.newUsers);
17873             }
17874         }
17875
17876         private void sendSystemPackageUpdatedBroadcastsInternal() {
17877             Bundle extras = new Bundle(2);
17878             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17879             extras.putBoolean(Intent.EXTRA_REPLACING, true);
17880             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17881                 removedPackage, extras, 0, null, null, null);
17882             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17883                 removedPackage, extras, 0, null, null, null);
17884             packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17885                 null, null, 0, removedPackage, null, null);
17886         }
17887
17888         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17889             // Don't send static shared library removal broadcasts as these
17890             // libs are visible only the the apps that depend on them an one
17891             // cannot remove the library if it has a dependency.
17892             if (isStaticSharedLib) {
17893                 return;
17894             }
17895             Bundle extras = new Bundle(2);
17896             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17897             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17898             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17899             if (isUpdate || isRemovedPackageSystemUpdate) {
17900                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
17901             }
17902             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17903             if (removedPackage != null) {
17904                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17905                     removedPackage, extras, 0, null, null, broadcastUsers);
17906                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
17907                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17908                         removedPackage, extras,
17909                         Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17910                         null, null, broadcastUsers);
17911                 }
17912             }
17913             if (removedAppId >= 0) {
17914                 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17915                     null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17916                     null, null, broadcastUsers);
17917             }
17918         }
17919
17920         void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17921             removedUsers = userIds;
17922             if (removedUsers == null) {
17923                 broadcastUsers = null;
17924                 return;
17925             }
17926
17927             broadcastUsers = EMPTY_INT_ARRAY;
17928             for (int i = userIds.length - 1; i >= 0; --i) {
17929                 final int userId = userIds[i];
17930                 if (deletedPackageSetting.getInstantApp(userId)) {
17931                     continue;
17932                 }
17933                 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17934             }
17935         }
17936     }
17937
17938     /*
17939      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17940      * flag is not set, the data directory is removed as well.
17941      * make sure this flag is set for partially installed apps. If not its meaningless to
17942      * delete a partially installed application.
17943      */
17944     private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17945             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17946         String packageName = ps.name;
17947         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17948         // Retrieve object to delete permissions for shared user later on
17949         final PackageParser.Package deletedPkg;
17950         final PackageSetting deletedPs;
17951         // reader
17952         synchronized (mPackages) {
17953             deletedPkg = mPackages.get(packageName);
17954             deletedPs = mSettings.mPackages.get(packageName);
17955             if (outInfo != null) {
17956                 outInfo.removedPackage = packageName;
17957                 outInfo.isStaticSharedLib = deletedPkg != null
17958                         && deletedPkg.staticSharedLibName != null;
17959                 outInfo.populateUsers(deletedPs == null ? null
17960                         : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
17961             }
17962         }
17963
17964         removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
17965
17966         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17967             final PackageParser.Package resolvedPkg;
17968             if (deletedPkg != null) {
17969                 resolvedPkg = deletedPkg;
17970             } else {
17971                 // We don't have a parsed package when it lives on an ejected
17972                 // adopted storage device, so fake something together
17973                 resolvedPkg = new PackageParser.Package(ps.name);
17974                 resolvedPkg.setVolumeUuid(ps.volumeUuid);
17975             }
17976             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17977                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17978             destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17979             if (outInfo != null) {
17980                 outInfo.dataRemoved = true;
17981             }
17982             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17983         }
17984
17985         int removedAppId = -1;
17986
17987         // writer
17988         synchronized (mPackages) {
17989             boolean installedStateChanged = false;
17990             if (deletedPs != null) {
17991                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17992                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17993                     clearDefaultBrowserIfNeeded(packageName);
17994                     mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17995                     removedAppId = mSettings.removePackageLPw(packageName);
17996                     if (outInfo != null) {
17997                         outInfo.removedAppId = removedAppId;
17998                     }
17999                     updatePermissionsLPw(deletedPs.name, null, 0);
18000                     if (deletedPs.sharedUser != null) {
18001                         // Remove permissions associated with package. Since runtime
18002                         // permissions are per user we have to kill the removed package
18003                         // or packages running under the shared user of the removed
18004                         // package if revoking the permissions requested only by the removed
18005                         // package is successful and this causes a change in gids.
18006                         for (int userId : UserManagerService.getInstance().getUserIds()) {
18007                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18008                                     userId);
18009                             if (userIdToKill == UserHandle.USER_ALL
18010                                     || userIdToKill >= UserHandle.USER_SYSTEM) {
18011                                 // If gids changed for this user, kill all affected packages.
18012                                 mHandler.post(new Runnable() {
18013                                     @Override
18014                                     public void run() {
18015                                         // This has to happen with no lock held.
18016                                         killApplication(deletedPs.name, deletedPs.appId,
18017                                                 KILL_APP_REASON_GIDS_CHANGED);
18018                                     }
18019                                 });
18020                                 break;
18021                             }
18022                         }
18023                     }
18024                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18025                 }
18026                 // make sure to preserve per-user disabled state if this removal was just
18027                 // a downgrade of a system app to the factory package
18028                 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18029                     if (DEBUG_REMOVE) {
18030                         Slog.d(TAG, "Propagating install state across downgrade");
18031                     }
18032                     for (int userId : allUserHandles) {
18033                         final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18034                         if (DEBUG_REMOVE) {
18035                             Slog.d(TAG, "    user " + userId + " => " + installed);
18036                         }
18037                         if (installed != ps.getInstalled(userId)) {
18038                             installedStateChanged = true;
18039                         }
18040                         ps.setInstalled(installed, userId);
18041                     }
18042                 }
18043             }
18044             // can downgrade to reader
18045             if (writeSettings) {
18046                 // Save settings now
18047                 mSettings.writeLPr();
18048             }
18049             if (installedStateChanged) {
18050                 mSettings.writeKernelMappingLPr(ps);
18051             }
18052         }
18053         if (removedAppId != -1) {
18054             // A user ID was deleted here. Go through all users and remove it
18055             // from KeyStore.
18056             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18057         }
18058     }
18059
18060     static boolean locationIsPrivileged(File path) {
18061         try {
18062             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18063                     .getCanonicalPath();
18064             return path.getCanonicalPath().startsWith(privilegedAppDir);
18065         } catch (IOException e) {
18066             Slog.e(TAG, "Unable to access code path " + path);
18067         }
18068         return false;
18069     }
18070
18071     /*
18072      * Tries to delete system package.
18073      */
18074     private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18075             PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18076             boolean writeSettings) {
18077         if (deletedPs.parentPackageName != null) {
18078             Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18079             return false;
18080         }
18081
18082         final boolean applyUserRestrictions
18083                 = (allUserHandles != null) && (outInfo.origUsers != null);
18084         final PackageSetting disabledPs;
18085         // Confirm if the system package has been updated
18086         // An updated system app can be deleted. This will also have to restore
18087         // the system pkg from system partition
18088         // reader
18089         synchronized (mPackages) {
18090             disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18091         }
18092
18093         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18094                 + " disabledPs=" + disabledPs);
18095
18096         if (disabledPs == null) {
18097             Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18098             return false;
18099         } else if (DEBUG_REMOVE) {
18100             Slog.d(TAG, "Deleting system pkg from data partition");
18101         }
18102
18103         if (DEBUG_REMOVE) {
18104             if (applyUserRestrictions) {
18105                 Slog.d(TAG, "Remembering install states:");
18106                 for (int userId : allUserHandles) {
18107                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18108                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18109                 }
18110             }
18111         }
18112
18113         // Delete the updated package
18114         outInfo.isRemovedPackageSystemUpdate = true;
18115         if (outInfo.removedChildPackages != null) {
18116             final int childCount = (deletedPs.childPackageNames != null)
18117                     ? deletedPs.childPackageNames.size() : 0;
18118             for (int i = 0; i < childCount; i++) {
18119                 String childPackageName = deletedPs.childPackageNames.get(i);
18120                 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18121                         .contains(childPackageName)) {
18122                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18123                             childPackageName);
18124                     if (childInfo != null) {
18125                         childInfo.isRemovedPackageSystemUpdate = true;
18126                     }
18127                 }
18128             }
18129         }
18130
18131         if (disabledPs.versionCode < deletedPs.versionCode) {
18132             // Delete data for downgrades
18133             flags &= ~PackageManager.DELETE_KEEP_DATA;
18134         } else {
18135             // Preserve data by setting flag
18136             flags |= PackageManager.DELETE_KEEP_DATA;
18137         }
18138
18139         boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18140                 outInfo, writeSettings, disabledPs.pkg);
18141         if (!ret) {
18142             return false;
18143         }
18144
18145         // writer
18146         synchronized (mPackages) {
18147             // Reinstate the old system package
18148             enableSystemPackageLPw(disabledPs.pkg);
18149             // Remove any native libraries from the upgraded package.
18150             removeNativeBinariesLI(deletedPs);
18151         }
18152
18153         // Install the system package
18154         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18155         int parseFlags = mDefParseFlags
18156                 | PackageParser.PARSE_MUST_BE_APK
18157                 | PackageParser.PARSE_IS_SYSTEM
18158                 | PackageParser.PARSE_IS_SYSTEM_DIR;
18159         if (locationIsPrivileged(disabledPs.codePath)) {
18160             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18161         }
18162
18163         final PackageParser.Package newPkg;
18164         try {
18165             newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18166                 0 /* currentTime */, null);
18167         } catch (PackageManagerException e) {
18168             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18169                     + e.getMessage());
18170             return false;
18171         }
18172
18173         try {
18174             // update shared libraries for the newly re-installed system package
18175             updateSharedLibrariesLPr(newPkg, null);
18176         } catch (PackageManagerException e) {
18177             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18178         }
18179
18180         prepareAppDataAfterInstallLIF(newPkg);
18181
18182         // writer
18183         synchronized (mPackages) {
18184             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18185
18186             // Propagate the permissions state as we do not want to drop on the floor
18187             // runtime permissions. The update permissions method below will take
18188             // care of removing obsolete permissions and grant install permissions.
18189             ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18190             updatePermissionsLPw(newPkg.packageName, newPkg,
18191                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18192
18193             if (applyUserRestrictions) {
18194                 boolean installedStateChanged = false;
18195                 if (DEBUG_REMOVE) {
18196                     Slog.d(TAG, "Propagating install state across reinstall");
18197                 }
18198                 for (int userId : allUserHandles) {
18199                     final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18200                     if (DEBUG_REMOVE) {
18201                         Slog.d(TAG, "    user " + userId + " => " + installed);
18202                     }
18203                     if (installed != ps.getInstalled(userId)) {
18204                         installedStateChanged = true;
18205                     }
18206                     ps.setInstalled(installed, userId);
18207
18208                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18209                 }
18210                 // Regardless of writeSettings we need to ensure that this restriction
18211                 // state propagation is persisted
18212                 mSettings.writeAllUsersPackageRestrictionsLPr();
18213                 if (installedStateChanged) {
18214                     mSettings.writeKernelMappingLPr(ps);
18215                 }
18216             }
18217             // can downgrade to reader here
18218             if (writeSettings) {
18219                 mSettings.writeLPr();
18220             }
18221         }
18222         return true;
18223     }
18224
18225     private boolean deleteInstalledPackageLIF(PackageSetting ps,
18226             boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18227             PackageRemovedInfo outInfo, boolean writeSettings,
18228             PackageParser.Package replacingPackage) {
18229         synchronized (mPackages) {
18230             if (outInfo != null) {
18231                 outInfo.uid = ps.appId;
18232             }
18233
18234             if (outInfo != null && outInfo.removedChildPackages != null) {
18235                 final int childCount = (ps.childPackageNames != null)
18236                         ? ps.childPackageNames.size() : 0;
18237                 for (int i = 0; i < childCount; i++) {
18238                     String childPackageName = ps.childPackageNames.get(i);
18239                     PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18240                     if (childPs == null) {
18241                         return false;
18242                     }
18243                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18244                             childPackageName);
18245                     if (childInfo != null) {
18246                         childInfo.uid = childPs.appId;
18247                     }
18248                 }
18249             }
18250         }
18251
18252         // Delete package data from internal structures and also remove data if flag is set
18253         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18254
18255         // Delete the child packages data
18256         final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18257         for (int i = 0; i < childCount; i++) {
18258             PackageSetting childPs;
18259             synchronized (mPackages) {
18260                 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18261             }
18262             if (childPs != null) {
18263                 PackageRemovedInfo childOutInfo = (outInfo != null
18264                         && outInfo.removedChildPackages != null)
18265                         ? outInfo.removedChildPackages.get(childPs.name) : null;
18266                 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18267                         && (replacingPackage != null
18268                         && !replacingPackage.hasChildPackage(childPs.name))
18269                         ? flags & ~DELETE_KEEP_DATA : flags;
18270                 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18271                         deleteFlags, writeSettings);
18272             }
18273         }
18274
18275         // Delete application code and resources only for parent packages
18276         if (ps.parentPackageName == null) {
18277             if (deleteCodeAndResources && (outInfo != null)) {
18278                 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18279                         ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18280                 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18281             }
18282         }
18283
18284         return true;
18285     }
18286
18287     @Override
18288     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18289             int userId) {
18290         mContext.enforceCallingOrSelfPermission(
18291                 android.Manifest.permission.DELETE_PACKAGES, null);
18292         synchronized (mPackages) {
18293             PackageSetting ps = mSettings.mPackages.get(packageName);
18294             if (ps == null) {
18295                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
18296                 return false;
18297             }
18298             // Cannot block uninstall of static shared libs as they are
18299             // considered a part of the using app (emulating static linking).
18300             // Also static libs are installed always on internal storage.
18301             PackageParser.Package pkg = mPackages.get(packageName);
18302             if (pkg != null && pkg.staticSharedLibName != null) {
18303                 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18304                         + " providing static shared library: " + pkg.staticSharedLibName);
18305                 return false;
18306             }
18307             if (!ps.getInstalled(userId)) {
18308                 // Can't block uninstall for an app that is not installed or enabled.
18309                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
18310                 return false;
18311             }
18312             ps.setBlockUninstall(blockUninstall, userId);
18313             mSettings.writePackageRestrictionsLPr(userId);
18314         }
18315         return true;
18316     }
18317
18318     @Override
18319     public boolean getBlockUninstallForUser(String packageName, int userId) {
18320         synchronized (mPackages) {
18321             PackageSetting ps = mSettings.mPackages.get(packageName);
18322             if (ps == null) {
18323                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
18324                 return false;
18325             }
18326             return ps.getBlockUninstall(userId);
18327         }
18328     }
18329
18330     @Override
18331     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18332         int callingUid = Binder.getCallingUid();
18333         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
18334             throw new SecurityException(
18335                     "setRequiredForSystemUser can only be run by the system or root");
18336         }
18337         synchronized (mPackages) {
18338             PackageSetting ps = mSettings.mPackages.get(packageName);
18339             if (ps == null) {
18340                 Log.w(TAG, "Package doesn't exist: " + packageName);
18341                 return false;
18342             }
18343             if (systemUserApp) {
18344                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18345             } else {
18346                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18347             }
18348             mSettings.writeLPr();
18349         }
18350         return true;
18351     }
18352
18353     /*
18354      * This method handles package deletion in general
18355      */
18356     private boolean deletePackageLIF(String packageName, UserHandle user,
18357             boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18358             PackageRemovedInfo outInfo, boolean writeSettings,
18359             PackageParser.Package replacingPackage) {
18360         if (packageName == null) {
18361             Slog.w(TAG, "Attempt to delete null packageName.");
18362             return false;
18363         }
18364
18365         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18366
18367         PackageSetting ps;
18368         synchronized (mPackages) {
18369             ps = mSettings.mPackages.get(packageName);
18370             if (ps == null) {
18371                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18372                 return false;
18373             }
18374
18375             if (ps.parentPackageName != null && (!isSystemApp(ps)
18376                     || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18377                 if (DEBUG_REMOVE) {
18378                     Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18379                             + ((user == null) ? UserHandle.USER_ALL : user));
18380                 }
18381                 final int removedUserId = (user != null) ? user.getIdentifier()
18382                         : UserHandle.USER_ALL;
18383                 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18384                     return false;
18385                 }
18386                 markPackageUninstalledForUserLPw(ps, user);
18387                 scheduleWritePackageRestrictionsLocked(user);
18388                 return true;
18389             }
18390         }
18391
18392         if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18393                 && user.getIdentifier() != UserHandle.USER_ALL)) {
18394             // The caller is asking that the package only be deleted for a single
18395             // user.  To do this, we just mark its uninstalled state and delete
18396             // its data. If this is a system app, we only allow this to happen if
18397             // they have set the special DELETE_SYSTEM_APP which requests different
18398             // semantics than normal for uninstalling system apps.
18399             markPackageUninstalledForUserLPw(ps, user);
18400
18401             if (!isSystemApp(ps)) {
18402                 // Do not uninstall the APK if an app should be cached
18403                 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18404                 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18405                     // Other user still have this package installed, so all
18406                     // we need to do is clear this user's data and save that
18407                     // it is uninstalled.
18408                     if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18409                     if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18410                         return false;
18411                     }
18412                     scheduleWritePackageRestrictionsLocked(user);
18413                     return true;
18414                 } else {
18415                     // We need to set it back to 'installed' so the uninstall
18416                     // broadcasts will be sent correctly.
18417                     if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18418                     ps.setInstalled(true, user.getIdentifier());
18419                     mSettings.writeKernelMappingLPr(ps);
18420                 }
18421             } else {
18422                 // This is a system app, so we assume that the
18423                 // other users still have this package installed, so all
18424                 // we need to do is clear this user's data and save that
18425                 // it is uninstalled.
18426                 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18427                 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18428                     return false;
18429                 }
18430                 scheduleWritePackageRestrictionsLocked(user);
18431                 return true;
18432             }
18433         }
18434
18435         // If we are deleting a composite package for all users, keep track
18436         // of result for each child.
18437         if (ps.childPackageNames != null && outInfo != null) {
18438             synchronized (mPackages) {
18439                 final int childCount = ps.childPackageNames.size();
18440                 outInfo.removedChildPackages = new ArrayMap<>(childCount);
18441                 for (int i = 0; i < childCount; i++) {
18442                     String childPackageName = ps.childPackageNames.get(i);
18443                     PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18444                     childInfo.removedPackage = childPackageName;
18445                     outInfo.removedChildPackages.put(childPackageName, childInfo);
18446                     PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18447                     if (childPs != null) {
18448                         childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18449                     }
18450                 }
18451             }
18452         }
18453
18454         boolean ret = false;
18455         if (isSystemApp(ps)) {
18456             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18457             // When an updated system application is deleted we delete the existing resources
18458             // as well and fall back to existing code in system partition
18459             ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18460         } else {
18461             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18462             ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18463                     outInfo, writeSettings, replacingPackage);
18464         }
18465
18466         // Take a note whether we deleted the package for all users
18467         if (outInfo != null) {
18468             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18469             if (outInfo.removedChildPackages != null) {
18470                 synchronized (mPackages) {
18471                     final int childCount = outInfo.removedChildPackages.size();
18472                     for (int i = 0; i < childCount; i++) {
18473                         PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18474                         if (childInfo != null) {
18475                             childInfo.removedForAllUsers = mPackages.get(
18476                                     childInfo.removedPackage) == null;
18477                         }
18478                     }
18479                 }
18480             }
18481             // If we uninstalled an update to a system app there may be some
18482             // child packages that appeared as they are declared in the system
18483             // app but were not declared in the update.
18484             if (isSystemApp(ps)) {
18485                 synchronized (mPackages) {
18486                     PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18487                     final int childCount = (updatedPs.childPackageNames != null)
18488                             ? updatedPs.childPackageNames.size() : 0;
18489                     for (int i = 0; i < childCount; i++) {
18490                         String childPackageName = updatedPs.childPackageNames.get(i);
18491                         if (outInfo.removedChildPackages == null
18492                                 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18493                             PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18494                             if (childPs == null) {
18495                                 continue;
18496                             }
18497                             PackageInstalledInfo installRes = new PackageInstalledInfo();
18498                             installRes.name = childPackageName;
18499                             installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18500                             installRes.pkg = mPackages.get(childPackageName);
18501                             installRes.uid = childPs.pkg.applicationInfo.uid;
18502                             if (outInfo.appearedChildPackages == null) {
18503                                 outInfo.appearedChildPackages = new ArrayMap<>();
18504                             }
18505                             outInfo.appearedChildPackages.put(childPackageName, installRes);
18506                         }
18507                     }
18508                 }
18509             }
18510         }
18511
18512         return ret;
18513     }
18514
18515     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18516         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18517                 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18518         for (int nextUserId : userIds) {
18519             if (DEBUG_REMOVE) {
18520                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18521             }
18522             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18523                     false /*installed*/,
18524                     true /*stopped*/,
18525                     true /*notLaunched*/,
18526                     false /*hidden*/,
18527                     false /*suspended*/,
18528                     false /*instantApp*/,
18529                     null /*lastDisableAppCaller*/,
18530                     null /*enabledComponents*/,
18531                     null /*disabledComponents*/,
18532                     false /*blockUninstall*/,
18533                     ps.readUserState(nextUserId).domainVerificationStatus,
18534                     0, PackageManager.INSTALL_REASON_UNKNOWN);
18535         }
18536         mSettings.writeKernelMappingLPr(ps);
18537     }
18538
18539     private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18540             PackageRemovedInfo outInfo) {
18541         final PackageParser.Package pkg;
18542         synchronized (mPackages) {
18543             pkg = mPackages.get(ps.name);
18544         }
18545
18546         final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18547                 : new int[] {userId};
18548         for (int nextUserId : userIds) {
18549             if (DEBUG_REMOVE) {
18550                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18551                         + nextUserId);
18552             }
18553
18554             destroyAppDataLIF(pkg, userId,
18555                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18556             destroyAppProfilesLIF(pkg, userId);
18557             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18558             schedulePackageCleaning(ps.name, nextUserId, false);
18559             synchronized (mPackages) {
18560                 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18561                     scheduleWritePackageRestrictionsLocked(nextUserId);
18562                 }
18563                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18564             }
18565         }
18566
18567         if (outInfo != null) {
18568             outInfo.removedPackage = ps.name;
18569             outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18570             outInfo.removedAppId = ps.appId;
18571             outInfo.removedUsers = userIds;
18572             outInfo.broadcastUsers = userIds;
18573         }
18574
18575         return true;
18576     }
18577
18578     private final class ClearStorageConnection implements ServiceConnection {
18579         IMediaContainerService mContainerService;
18580
18581         @Override
18582         public void onServiceConnected(ComponentName name, IBinder service) {
18583             synchronized (this) {
18584                 mContainerService = IMediaContainerService.Stub
18585                         .asInterface(Binder.allowBlocking(service));
18586                 notifyAll();
18587             }
18588         }
18589
18590         @Override
18591         public void onServiceDisconnected(ComponentName name) {
18592         }
18593     }
18594
18595     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18596         if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18597
18598         final boolean mounted;
18599         if (Environment.isExternalStorageEmulated()) {
18600             mounted = true;
18601         } else {
18602             final String status = Environment.getExternalStorageState();
18603
18604             mounted = status.equals(Environment.MEDIA_MOUNTED)
18605                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18606         }
18607
18608         if (!mounted) {
18609             return;
18610         }
18611
18612         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18613         int[] users;
18614         if (userId == UserHandle.USER_ALL) {
18615             users = sUserManager.getUserIds();
18616         } else {
18617             users = new int[] { userId };
18618         }
18619         final ClearStorageConnection conn = new ClearStorageConnection();
18620         if (mContext.bindServiceAsUser(
18621                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18622             try {
18623                 for (int curUser : users) {
18624                     long timeout = SystemClock.uptimeMillis() + 5000;
18625                     synchronized (conn) {
18626                         long now;
18627                         while (conn.mContainerService == null &&
18628                                 (now = SystemClock.uptimeMillis()) < timeout) {
18629                             try {
18630                                 conn.wait(timeout - now);
18631                             } catch (InterruptedException e) {
18632                             }
18633                         }
18634                     }
18635                     if (conn.mContainerService == null) {
18636                         return;
18637                     }
18638
18639                     final UserEnvironment userEnv = new UserEnvironment(curUser);
18640                     clearDirectory(conn.mContainerService,
18641                             userEnv.buildExternalStorageAppCacheDirs(packageName));
18642                     if (allData) {
18643                         clearDirectory(conn.mContainerService,
18644                                 userEnv.buildExternalStorageAppDataDirs(packageName));
18645                         clearDirectory(conn.mContainerService,
18646                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
18647                     }
18648                 }
18649             } finally {
18650                 mContext.unbindService(conn);
18651             }
18652         }
18653     }
18654
18655     @Override
18656     public void clearApplicationProfileData(String packageName) {
18657         enforceSystemOrRoot("Only the system can clear all profile data");
18658
18659         final PackageParser.Package pkg;
18660         synchronized (mPackages) {
18661             pkg = mPackages.get(packageName);
18662         }
18663
18664         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18665             synchronized (mInstallLock) {
18666                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18667             }
18668         }
18669     }
18670
18671     @Override
18672     public void clearApplicationUserData(final String packageName,
18673             final IPackageDataObserver observer, final int userId) {
18674         mContext.enforceCallingOrSelfPermission(
18675                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18676
18677         enforceCrossUserPermission(Binder.getCallingUid(), userId,
18678                 true /* requireFullPermission */, false /* checkShell */, "clear application data");
18679
18680         if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18681             throw new SecurityException("Cannot clear data for a protected package: "
18682                     + packageName);
18683         }
18684         // Queue up an async operation since the package deletion may take a little while.
18685         mHandler.post(new Runnable() {
18686             public void run() {
18687                 mHandler.removeCallbacks(this);
18688                 final boolean succeeded;
18689                 try (PackageFreezer freezer = freezePackage(packageName,
18690                         "clearApplicationUserData")) {
18691                     synchronized (mInstallLock) {
18692                         succeeded = clearApplicationUserDataLIF(packageName, userId);
18693                     }
18694                     clearExternalStorageDataSync(packageName, userId, true);
18695                     synchronized (mPackages) {
18696                         mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18697                                 packageName, userId);
18698                     }
18699                 }
18700                 if (succeeded) {
18701                     // invoke DeviceStorageMonitor's update method to clear any notifications
18702                     DeviceStorageMonitorInternal dsm = LocalServices
18703                             .getService(DeviceStorageMonitorInternal.class);
18704                     if (dsm != null) {
18705                         dsm.checkMemory();
18706                     }
18707                 }
18708                 if(observer != null) {
18709                     try {
18710                         observer.onRemoveCompleted(packageName, succeeded);
18711                     } catch (RemoteException e) {
18712                         Log.i(TAG, "Observer no longer exists.");
18713                     }
18714                 } //end if observer
18715             } //end run
18716         });
18717     }
18718
18719     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18720         if (packageName == null) {
18721             Slog.w(TAG, "Attempt to delete null packageName.");
18722             return false;
18723         }
18724
18725         // Try finding details about the requested package
18726         PackageParser.Package pkg;
18727         synchronized (mPackages) {
18728             pkg = mPackages.get(packageName);
18729             if (pkg == null) {
18730                 final PackageSetting ps = mSettings.mPackages.get(packageName);
18731                 if (ps != null) {
18732                     pkg = ps.pkg;
18733                 }
18734             }
18735
18736             if (pkg == null) {
18737                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18738                 return false;
18739             }
18740
18741             PackageSetting ps = (PackageSetting) pkg.mExtras;
18742             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18743         }
18744
18745         clearAppDataLIF(pkg, userId,
18746                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18747
18748         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18749         removeKeystoreDataIfNeeded(userId, appId);
18750
18751         UserManagerInternal umInternal = getUserManagerInternal();
18752         final int flags;
18753         if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18754             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18755         } else if (umInternal.isUserRunning(userId)) {
18756             flags = StorageManager.FLAG_STORAGE_DE;
18757         } else {
18758             flags = 0;
18759         }
18760         prepareAppDataContentsLIF(pkg, userId, flags);
18761
18762         return true;
18763     }
18764
18765     /**
18766      * Reverts user permission state changes (permissions and flags) in
18767      * all packages for a given user.
18768      *
18769      * @param userId The device user for which to do a reset.
18770      */
18771     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18772         final int packageCount = mPackages.size();
18773         for (int i = 0; i < packageCount; i++) {
18774             PackageParser.Package pkg = mPackages.valueAt(i);
18775             PackageSetting ps = (PackageSetting) pkg.mExtras;
18776             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18777         }
18778     }
18779
18780     private void resetNetworkPolicies(int userId) {
18781         LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18782     }
18783
18784     /**
18785      * Reverts user permission state changes (permissions and flags).
18786      *
18787      * @param ps The package for which to reset.
18788      * @param userId The device user for which to do a reset.
18789      */
18790     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18791             final PackageSetting ps, final int userId) {
18792         if (ps.pkg == null) {
18793             return;
18794         }
18795
18796         // These are flags that can change base on user actions.
18797         final int userSettableMask = FLAG_PERMISSION_USER_SET
18798                 | FLAG_PERMISSION_USER_FIXED
18799                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18800                 | FLAG_PERMISSION_REVIEW_REQUIRED;
18801
18802         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18803                 | FLAG_PERMISSION_POLICY_FIXED;
18804
18805         boolean writeInstallPermissions = false;
18806         boolean writeRuntimePermissions = false;
18807
18808         final int permissionCount = ps.pkg.requestedPermissions.size();
18809         for (int i = 0; i < permissionCount; i++) {
18810             String permission = ps.pkg.requestedPermissions.get(i);
18811
18812             BasePermission bp = mSettings.mPermissions.get(permission);
18813             if (bp == null) {
18814                 continue;
18815             }
18816
18817             // If shared user we just reset the state to which only this app contributed.
18818             if (ps.sharedUser != null) {
18819                 boolean used = false;
18820                 final int packageCount = ps.sharedUser.packages.size();
18821                 for (int j = 0; j < packageCount; j++) {
18822                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18823                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18824                             && pkg.pkg.requestedPermissions.contains(permission)) {
18825                         used = true;
18826                         break;
18827                     }
18828                 }
18829                 if (used) {
18830                     continue;
18831                 }
18832             }
18833
18834             PermissionsState permissionsState = ps.getPermissionsState();
18835
18836             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
18837
18838             // Always clear the user settable flags.
18839             final boolean hasInstallState = permissionsState.getInstallPermissionState(
18840                     bp.name) != null;
18841             // If permission review is enabled and this is a legacy app, mark the
18842             // permission as requiring a review as this is the initial state.
18843             int flags = 0;
18844             if (mPermissionReviewRequired
18845                     && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18846                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18847             }
18848             if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18849                 if (hasInstallState) {
18850                     writeInstallPermissions = true;
18851                 } else {
18852                     writeRuntimePermissions = true;
18853                 }
18854             }
18855
18856             // Below is only runtime permission handling.
18857             if (!bp.isRuntime()) {
18858                 continue;
18859             }
18860
18861             // Never clobber system or policy.
18862             if ((oldFlags & policyOrSystemFlags) != 0) {
18863                 continue;
18864             }
18865
18866             // If this permission was granted by default, make sure it is.
18867             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18868                 if (permissionsState.grantRuntimePermission(bp, userId)
18869                         != PERMISSION_OPERATION_FAILURE) {
18870                     writeRuntimePermissions = true;
18871                 }
18872             // If permission review is enabled the permissions for a legacy apps
18873             // are represented as constantly granted runtime ones, so don't revoke.
18874             } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18875                 // Otherwise, reset the permission.
18876                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18877                 switch (revokeResult) {
18878                     case PERMISSION_OPERATION_SUCCESS:
18879                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18880                         writeRuntimePermissions = true;
18881                         final int appId = ps.appId;
18882                         mHandler.post(new Runnable() {
18883                             @Override
18884                             public void run() {
18885                                 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18886                             }
18887                         });
18888                     } break;
18889                 }
18890             }
18891         }
18892
18893         // Synchronously write as we are taking permissions away.
18894         if (writeRuntimePermissions) {
18895             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18896         }
18897
18898         // Synchronously write as we are taking permissions away.
18899         if (writeInstallPermissions) {
18900             mSettings.writeLPr();
18901         }
18902     }
18903
18904     /**
18905      * Remove entries from the keystore daemon. Will only remove it if the
18906      * {@code appId} is valid.
18907      */
18908     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18909         if (appId < 0) {
18910             return;
18911         }
18912
18913         final KeyStore keyStore = KeyStore.getInstance();
18914         if (keyStore != null) {
18915             if (userId == UserHandle.USER_ALL) {
18916                 for (final int individual : sUserManager.getUserIds()) {
18917                     keyStore.clearUid(UserHandle.getUid(individual, appId));
18918                 }
18919             } else {
18920                 keyStore.clearUid(UserHandle.getUid(userId, appId));
18921             }
18922         } else {
18923             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18924         }
18925     }
18926
18927     @Override
18928     public void deleteApplicationCacheFiles(final String packageName,
18929             final IPackageDataObserver observer) {
18930         final int userId = UserHandle.getCallingUserId();
18931         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18932     }
18933
18934     @Override
18935     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18936             final IPackageDataObserver observer) {
18937         mContext.enforceCallingOrSelfPermission(
18938                 android.Manifest.permission.DELETE_CACHE_FILES, null);
18939         enforceCrossUserPermission(Binder.getCallingUid(), userId,
18940                 /* requireFullPermission= */ true, /* checkShell= */ false,
18941                 "delete application cache files");
18942
18943         final PackageParser.Package pkg;
18944         synchronized (mPackages) {
18945             pkg = mPackages.get(packageName);
18946         }
18947
18948         // Queue up an async operation since the package deletion may take a little while.
18949         mHandler.post(new Runnable() {
18950             public void run() {
18951                 synchronized (mInstallLock) {
18952                     final int flags = StorageManager.FLAG_STORAGE_DE
18953                             | StorageManager.FLAG_STORAGE_CE;
18954                     // We're only clearing cache files, so we don't care if the
18955                     // app is unfrozen and still able to run
18956                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18957                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18958                 }
18959                 clearExternalStorageDataSync(packageName, userId, false);
18960                 if (observer != null) {
18961                     try {
18962                         observer.onRemoveCompleted(packageName, true);
18963                     } catch (RemoteException e) {
18964                         Log.i(TAG, "Observer no longer exists.");
18965                     }
18966                 }
18967             }
18968         });
18969     }
18970
18971     @Override
18972     public void getPackageSizeInfo(final String packageName, int userHandle,
18973             final IPackageStatsObserver observer) {
18974         throw new UnsupportedOperationException(
18975                 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18976     }
18977
18978     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18979         final PackageSetting ps;
18980         synchronized (mPackages) {
18981             ps = mSettings.mPackages.get(packageName);
18982             if (ps == null) {
18983                 Slog.w(TAG, "Failed to find settings for " + packageName);
18984                 return false;
18985             }
18986         }
18987
18988         final String[] packageNames = { packageName };
18989         final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18990         final String[] codePaths = { ps.codePathString };
18991
18992         try {
18993             mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18994                     ps.appId, ceDataInodes, codePaths, stats);
18995
18996             // For now, ignore code size of packages on system partition
18997             if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18998                 stats.codeSize = 0;
18999             }
19000
19001             // External clients expect these to be tracked separately
19002             stats.dataSize -= stats.cacheSize;
19003
19004         } catch (InstallerException e) {
19005             Slog.w(TAG, String.valueOf(e));
19006             return false;
19007         }
19008
19009         return true;
19010     }
19011
19012     private int getUidTargetSdkVersionLockedLPr(int uid) {
19013         Object obj = mSettings.getUserIdLPr(uid);
19014         if (obj instanceof SharedUserSetting) {
19015             final SharedUserSetting sus = (SharedUserSetting) obj;
19016             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19017             final Iterator<PackageSetting> it = sus.packages.iterator();
19018             while (it.hasNext()) {
19019                 final PackageSetting ps = it.next();
19020                 if (ps.pkg != null) {
19021                     int v = ps.pkg.applicationInfo.targetSdkVersion;
19022                     if (v < vers) vers = v;
19023                 }
19024             }
19025             return vers;
19026         } else if (obj instanceof PackageSetting) {
19027             final PackageSetting ps = (PackageSetting) obj;
19028             if (ps.pkg != null) {
19029                 return ps.pkg.applicationInfo.targetSdkVersion;
19030             }
19031         }
19032         return Build.VERSION_CODES.CUR_DEVELOPMENT;
19033     }
19034
19035     @Override
19036     public void addPreferredActivity(IntentFilter filter, int match,
19037             ComponentName[] set, ComponentName activity, int userId) {
19038         addPreferredActivityInternal(filter, match, set, activity, true, userId,
19039                 "Adding preferred");
19040     }
19041
19042     private void addPreferredActivityInternal(IntentFilter filter, int match,
19043             ComponentName[] set, ComponentName activity, boolean always, int userId,
19044             String opname) {
19045         // writer
19046         int callingUid = Binder.getCallingUid();
19047         enforceCrossUserPermission(callingUid, userId,
19048                 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19049         if (filter.countActions() == 0) {
19050             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19051             return;
19052         }
19053         synchronized (mPackages) {
19054             if (mContext.checkCallingOrSelfPermission(
19055                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19056                     != PackageManager.PERMISSION_GRANTED) {
19057                 if (getUidTargetSdkVersionLockedLPr(callingUid)
19058                         < Build.VERSION_CODES.FROYO) {
19059                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19060                             + callingUid);
19061                     return;
19062                 }
19063                 mContext.enforceCallingOrSelfPermission(
19064                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19065             }
19066
19067             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19068             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19069                     + userId + ":");
19070             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19071             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19072             scheduleWritePackageRestrictionsLocked(userId);
19073             postPreferredActivityChangedBroadcast(userId);
19074         }
19075     }
19076
19077     private void postPreferredActivityChangedBroadcast(int userId) {
19078         mHandler.post(() -> {
19079             final IActivityManager am = ActivityManager.getService();
19080             if (am == null) {
19081                 return;
19082             }
19083
19084             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19085             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19086             try {
19087                 am.broadcastIntent(null, intent, null, null,
19088                         0, null, null, null, android.app.AppOpsManager.OP_NONE,
19089                         null, false, false, userId);
19090             } catch (RemoteException e) {
19091             }
19092         });
19093     }
19094
19095     @Override
19096     public void replacePreferredActivity(IntentFilter filter, int match,
19097             ComponentName[] set, ComponentName activity, int userId) {
19098         if (filter.countActions() != 1) {
19099             throw new IllegalArgumentException(
19100                     "replacePreferredActivity expects filter to have only 1 action.");
19101         }
19102         if (filter.countDataAuthorities() != 0
19103                 || filter.countDataPaths() != 0
19104                 || filter.countDataSchemes() > 1
19105                 || filter.countDataTypes() != 0) {
19106             throw new IllegalArgumentException(
19107                     "replacePreferredActivity expects filter to have no data authorities, " +
19108                     "paths, or types; and at most one scheme.");
19109         }
19110
19111         final int callingUid = Binder.getCallingUid();
19112         enforceCrossUserPermission(callingUid, userId,
19113                 true /* requireFullPermission */, false /* checkShell */,
19114                 "replace preferred activity");
19115         synchronized (mPackages) {
19116             if (mContext.checkCallingOrSelfPermission(
19117                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19118                     != PackageManager.PERMISSION_GRANTED) {
19119                 if (getUidTargetSdkVersionLockedLPr(callingUid)
19120                         < Build.VERSION_CODES.FROYO) {
19121                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19122                             + Binder.getCallingUid());
19123                     return;
19124                 }
19125                 mContext.enforceCallingOrSelfPermission(
19126                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19127             }
19128
19129             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19130             if (pir != null) {
19131                 // Get all of the existing entries that exactly match this filter.
19132                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19133                 if (existing != null && existing.size() == 1) {
19134                     PreferredActivity cur = existing.get(0);
19135                     if (DEBUG_PREFERRED) {
19136                         Slog.i(TAG, "Checking replace of preferred:");
19137                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19138                         if (!cur.mPref.mAlways) {
19139                             Slog.i(TAG, "  -- CUR; not mAlways!");
19140                         } else {
19141                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19142                             Slog.i(TAG, "  -- CUR: mSet="
19143                                     + Arrays.toString(cur.mPref.mSetComponents));
19144                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19145                             Slog.i(TAG, "  -- NEW: mMatch="
19146                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
19147                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19148                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19149                         }
19150                     }
19151                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19152                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19153                             && cur.mPref.sameSet(set)) {
19154                         // Setting the preferred activity to what it happens to be already
19155                         if (DEBUG_PREFERRED) {
19156                             Slog.i(TAG, "Replacing with same preferred activity "
19157                                     + cur.mPref.mShortComponent + " for user "
19158                                     + userId + ":");
19159                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19160                         }
19161                         return;
19162                     }
19163                 }
19164
19165                 if (existing != null) {
19166                     if (DEBUG_PREFERRED) {
19167                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
19168                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19169                     }
19170                     for (int i = 0; i < existing.size(); i++) {
19171                         PreferredActivity pa = existing.get(i);
19172                         if (DEBUG_PREFERRED) {
19173                             Slog.i(TAG, "Removing existing preferred activity "
19174                                     + pa.mPref.mComponent + ":");
19175                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19176                         }
19177                         pir.removeFilter(pa);
19178                     }
19179                 }
19180             }
19181             addPreferredActivityInternal(filter, match, set, activity, true, userId,
19182                     "Replacing preferred");
19183         }
19184     }
19185
19186     @Override
19187     public void clearPackagePreferredActivities(String packageName) {
19188         final int uid = Binder.getCallingUid();
19189         // writer
19190         synchronized (mPackages) {
19191             PackageParser.Package pkg = mPackages.get(packageName);
19192             if (pkg == null || pkg.applicationInfo.uid != uid) {
19193                 if (mContext.checkCallingOrSelfPermission(
19194                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19195                         != PackageManager.PERMISSION_GRANTED) {
19196                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
19197                             < Build.VERSION_CODES.FROYO) {
19198                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19199                                 + Binder.getCallingUid());
19200                         return;
19201                     }
19202                     mContext.enforceCallingOrSelfPermission(
19203                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19204                 }
19205             }
19206
19207             int user = UserHandle.getCallingUserId();
19208             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19209                 scheduleWritePackageRestrictionsLocked(user);
19210             }
19211         }
19212     }
19213
19214     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19215     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19216         ArrayList<PreferredActivity> removed = null;
19217         boolean changed = false;
19218         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19219             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19220             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19221             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19222                 continue;
19223             }
19224             Iterator<PreferredActivity> it = pir.filterIterator();
19225             while (it.hasNext()) {
19226                 PreferredActivity pa = it.next();
19227                 // Mark entry for removal only if it matches the package name
19228                 // and the entry is of type "always".
19229                 if (packageName == null ||
19230                         (pa.mPref.mComponent.getPackageName().equals(packageName)
19231                                 && pa.mPref.mAlways)) {
19232                     if (removed == null) {
19233                         removed = new ArrayList<PreferredActivity>();
19234                     }
19235                     removed.add(pa);
19236                 }
19237             }
19238             if (removed != null) {
19239                 for (int j=0; j<removed.size(); j++) {
19240                     PreferredActivity pa = removed.get(j);
19241                     pir.removeFilter(pa);
19242                 }
19243                 changed = true;
19244             }
19245         }
19246         if (changed) {
19247             postPreferredActivityChangedBroadcast(userId);
19248         }
19249         return changed;
19250     }
19251
19252     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19253     private void clearIntentFilterVerificationsLPw(int userId) {
19254         final int packageCount = mPackages.size();
19255         for (int i = 0; i < packageCount; i++) {
19256             PackageParser.Package pkg = mPackages.valueAt(i);
19257             clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19258         }
19259     }
19260
19261     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19262     void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19263         if (userId == UserHandle.USER_ALL) {
19264             if (mSettings.removeIntentFilterVerificationLPw(packageName,
19265                     sUserManager.getUserIds())) {
19266                 for (int oneUserId : sUserManager.getUserIds()) {
19267                     scheduleWritePackageRestrictionsLocked(oneUserId);
19268                 }
19269             }
19270         } else {
19271             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19272                 scheduleWritePackageRestrictionsLocked(userId);
19273             }
19274         }
19275     }
19276
19277     void clearDefaultBrowserIfNeeded(String packageName) {
19278         for (int oneUserId : sUserManager.getUserIds()) {
19279             String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
19280             if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
19281             if (packageName.equals(defaultBrowserPackageName)) {
19282                 setDefaultBrowserPackageName(null, oneUserId);
19283             }
19284         }
19285     }
19286
19287     @Override
19288     public void resetApplicationPreferences(int userId) {
19289         mContext.enforceCallingOrSelfPermission(
19290                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19291         final long identity = Binder.clearCallingIdentity();
19292         // writer
19293         try {
19294             synchronized (mPackages) {
19295                 clearPackagePreferredActivitiesLPw(null, userId);
19296                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
19297                 // TODO: We have to reset the default SMS and Phone. This requires
19298                 // significant refactoring to keep all default apps in the package
19299                 // manager (cleaner but more work) or have the services provide
19300                 // callbacks to the package manager to request a default app reset.
19301                 applyFactoryDefaultBrowserLPw(userId);
19302                 clearIntentFilterVerificationsLPw(userId);
19303                 primeDomainVerificationsLPw(userId);
19304                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19305                 scheduleWritePackageRestrictionsLocked(userId);
19306             }
19307             resetNetworkPolicies(userId);
19308         } finally {
19309             Binder.restoreCallingIdentity(identity);
19310         }
19311     }
19312
19313     @Override
19314     public int getPreferredActivities(List<IntentFilter> outFilters,
19315             List<ComponentName> outActivities, String packageName) {
19316
19317         int num = 0;
19318         final int userId = UserHandle.getCallingUserId();
19319         // reader
19320         synchronized (mPackages) {
19321             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19322             if (pir != null) {
19323                 final Iterator<PreferredActivity> it = pir.filterIterator();
19324                 while (it.hasNext()) {
19325                     final PreferredActivity pa = it.next();
19326                     if (packageName == null
19327                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
19328                                     && pa.mPref.mAlways)) {
19329                         if (outFilters != null) {
19330                             outFilters.add(new IntentFilter(pa));
19331                         }
19332                         if (outActivities != null) {
19333                             outActivities.add(pa.mPref.mComponent);
19334                         }
19335                     }
19336                 }
19337             }
19338         }
19339
19340         return num;
19341     }
19342
19343     @Override
19344     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19345             int userId) {
19346         int callingUid = Binder.getCallingUid();
19347         if (callingUid != Process.SYSTEM_UID) {
19348             throw new SecurityException(
19349                     "addPersistentPreferredActivity can only be run by the system");
19350         }
19351         if (filter.countActions() == 0) {
19352             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19353             return;
19354         }
19355         synchronized (mPackages) {
19356             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19357                     ":");
19358             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19359             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19360                     new PersistentPreferredActivity(filter, activity));
19361             scheduleWritePackageRestrictionsLocked(userId);
19362             postPreferredActivityChangedBroadcast(userId);
19363         }
19364     }
19365
19366     @Override
19367     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19368         int callingUid = Binder.getCallingUid();
19369         if (callingUid != Process.SYSTEM_UID) {
19370             throw new SecurityException(
19371                     "clearPackagePersistentPreferredActivities can only be run by the system");
19372         }
19373         ArrayList<PersistentPreferredActivity> removed = null;
19374         boolean changed = false;
19375         synchronized (mPackages) {
19376             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19377                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19378                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19379                         .valueAt(i);
19380                 if (userId != thisUserId) {
19381                     continue;
19382                 }
19383                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19384                 while (it.hasNext()) {
19385                     PersistentPreferredActivity ppa = it.next();
19386                     // Mark entry for removal only if it matches the package name.
19387                     if (ppa.mComponent.getPackageName().equals(packageName)) {
19388                         if (removed == null) {
19389                             removed = new ArrayList<PersistentPreferredActivity>();
19390                         }
19391                         removed.add(ppa);
19392                     }
19393                 }
19394                 if (removed != null) {
19395                     for (int j=0; j<removed.size(); j++) {
19396                         PersistentPreferredActivity ppa = removed.get(j);
19397                         ppir.removeFilter(ppa);
19398                     }
19399                     changed = true;
19400                 }
19401             }
19402
19403             if (changed) {
19404                 scheduleWritePackageRestrictionsLocked(userId);
19405                 postPreferredActivityChangedBroadcast(userId);
19406             }
19407         }
19408     }
19409
19410     /**
19411      * Common machinery for picking apart a restored XML blob and passing
19412      * it to a caller-supplied functor to be applied to the running system.
19413      */
19414     private void restoreFromXml(XmlPullParser parser, int userId,
19415             String expectedStartTag, BlobXmlRestorer functor)
19416             throws IOException, XmlPullParserException {
19417         int type;
19418         while ((type = parser.next()) != XmlPullParser.START_TAG
19419                 && type != XmlPullParser.END_DOCUMENT) {
19420         }
19421         if (type != XmlPullParser.START_TAG) {
19422             // oops didn't find a start tag?!
19423             if (DEBUG_BACKUP) {
19424                 Slog.e(TAG, "Didn't find start tag during restore");
19425             }
19426             return;
19427         }
19428 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19429         // this is supposed to be TAG_PREFERRED_BACKUP
19430         if (!expectedStartTag.equals(parser.getName())) {
19431             if (DEBUG_BACKUP) {
19432                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
19433             }
19434             return;
19435         }
19436
19437         // skip interfering stuff, then we're aligned with the backing implementation
19438         while ((type = parser.next()) == XmlPullParser.TEXT) { }
19439 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19440         functor.apply(parser, userId);
19441     }
19442
19443     private interface BlobXmlRestorer {
19444         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19445     }
19446
19447     /**
19448      * Non-Binder method, support for the backup/restore mechanism: write the
19449      * full set of preferred activities in its canonical XML format.  Returns the
19450      * XML output as a byte array, or null if there is none.
19451      */
19452     @Override
19453     public byte[] getPreferredActivityBackup(int userId) {
19454         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19455             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19456         }
19457
19458         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19459         try {
19460             final XmlSerializer serializer = new FastXmlSerializer();
19461             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19462             serializer.startDocument(null, true);
19463             serializer.startTag(null, TAG_PREFERRED_BACKUP);
19464
19465             synchronized (mPackages) {
19466                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19467             }
19468
19469             serializer.endTag(null, TAG_PREFERRED_BACKUP);
19470             serializer.endDocument();
19471             serializer.flush();
19472         } catch (Exception e) {
19473             if (DEBUG_BACKUP) {
19474                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
19475             }
19476             return null;
19477         }
19478
19479         return dataStream.toByteArray();
19480     }
19481
19482     @Override
19483     public void restorePreferredActivities(byte[] backup, int userId) {
19484         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19485             throw new SecurityException("Only the system may call restorePreferredActivities()");
19486         }
19487
19488         try {
19489             final XmlPullParser parser = Xml.newPullParser();
19490             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19491             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19492                     new BlobXmlRestorer() {
19493                         @Override
19494                         public void apply(XmlPullParser parser, int userId)
19495                                 throws XmlPullParserException, IOException {
19496                             synchronized (mPackages) {
19497                                 mSettings.readPreferredActivitiesLPw(parser, userId);
19498                             }
19499                         }
19500                     } );
19501         } catch (Exception e) {
19502             if (DEBUG_BACKUP) {
19503                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19504             }
19505         }
19506     }
19507
19508     /**
19509      * Non-Binder method, support for the backup/restore mechanism: write the
19510      * default browser (etc) settings in its canonical XML format.  Returns the default
19511      * browser XML representation as a byte array, or null if there is none.
19512      */
19513     @Override
19514     public byte[] getDefaultAppsBackup(int userId) {
19515         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19516             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19517         }
19518
19519         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19520         try {
19521             final XmlSerializer serializer = new FastXmlSerializer();
19522             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19523             serializer.startDocument(null, true);
19524             serializer.startTag(null, TAG_DEFAULT_APPS);
19525
19526             synchronized (mPackages) {
19527                 mSettings.writeDefaultAppsLPr(serializer, userId);
19528             }
19529
19530             serializer.endTag(null, TAG_DEFAULT_APPS);
19531             serializer.endDocument();
19532             serializer.flush();
19533         } catch (Exception e) {
19534             if (DEBUG_BACKUP) {
19535                 Slog.e(TAG, "Unable to write default apps for backup", e);
19536             }
19537             return null;
19538         }
19539
19540         return dataStream.toByteArray();
19541     }
19542
19543     @Override
19544     public void restoreDefaultApps(byte[] backup, int userId) {
19545         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19546             throw new SecurityException("Only the system may call restoreDefaultApps()");
19547         }
19548
19549         try {
19550             final XmlPullParser parser = Xml.newPullParser();
19551             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19552             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19553                     new BlobXmlRestorer() {
19554                         @Override
19555                         public void apply(XmlPullParser parser, int userId)
19556                                 throws XmlPullParserException, IOException {
19557                             synchronized (mPackages) {
19558                                 mSettings.readDefaultAppsLPw(parser, userId);
19559                             }
19560                         }
19561                     } );
19562         } catch (Exception e) {
19563             if (DEBUG_BACKUP) {
19564                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19565             }
19566         }
19567     }
19568
19569     @Override
19570     public byte[] getIntentFilterVerificationBackup(int userId) {
19571         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19572             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19573         }
19574
19575         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19576         try {
19577             final XmlSerializer serializer = new FastXmlSerializer();
19578             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19579             serializer.startDocument(null, true);
19580             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19581
19582             synchronized (mPackages) {
19583                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19584             }
19585
19586             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19587             serializer.endDocument();
19588             serializer.flush();
19589         } catch (Exception e) {
19590             if (DEBUG_BACKUP) {
19591                 Slog.e(TAG, "Unable to write default apps for backup", e);
19592             }
19593             return null;
19594         }
19595
19596         return dataStream.toByteArray();
19597     }
19598
19599     @Override
19600     public void restoreIntentFilterVerification(byte[] backup, int userId) {
19601         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19602             throw new SecurityException("Only the system may call restorePreferredActivities()");
19603         }
19604
19605         try {
19606             final XmlPullParser parser = Xml.newPullParser();
19607             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19608             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19609                     new BlobXmlRestorer() {
19610                         @Override
19611                         public void apply(XmlPullParser parser, int userId)
19612                                 throws XmlPullParserException, IOException {
19613                             synchronized (mPackages) {
19614                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
19615                                 mSettings.writeLPr();
19616                             }
19617                         }
19618                     } );
19619         } catch (Exception e) {
19620             if (DEBUG_BACKUP) {
19621                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19622             }
19623         }
19624     }
19625
19626     @Override
19627     public byte[] getPermissionGrantBackup(int userId) {
19628         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19629             throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19630         }
19631
19632         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19633         try {
19634             final XmlSerializer serializer = new FastXmlSerializer();
19635             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19636             serializer.startDocument(null, true);
19637             serializer.startTag(null, TAG_PERMISSION_BACKUP);
19638
19639             synchronized (mPackages) {
19640                 serializeRuntimePermissionGrantsLPr(serializer, userId);
19641             }
19642
19643             serializer.endTag(null, TAG_PERMISSION_BACKUP);
19644             serializer.endDocument();
19645             serializer.flush();
19646         } catch (Exception e) {
19647             if (DEBUG_BACKUP) {
19648                 Slog.e(TAG, "Unable to write default apps for backup", e);
19649             }
19650             return null;
19651         }
19652
19653         return dataStream.toByteArray();
19654     }
19655
19656     @Override
19657     public void restorePermissionGrants(byte[] backup, int userId) {
19658         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19659             throw new SecurityException("Only the system may call restorePermissionGrants()");
19660         }
19661
19662         try {
19663             final XmlPullParser parser = Xml.newPullParser();
19664             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19665             restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19666                     new BlobXmlRestorer() {
19667                         @Override
19668                         public void apply(XmlPullParser parser, int userId)
19669                                 throws XmlPullParserException, IOException {
19670                             synchronized (mPackages) {
19671                                 processRestoredPermissionGrantsLPr(parser, userId);
19672                             }
19673                         }
19674                     } );
19675         } catch (Exception e) {
19676             if (DEBUG_BACKUP) {
19677                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19678             }
19679         }
19680     }
19681
19682     private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19683             throws IOException {
19684         serializer.startTag(null, TAG_ALL_GRANTS);
19685
19686         final int N = mSettings.mPackages.size();
19687         for (int i = 0; i < N; i++) {
19688             final PackageSetting ps = mSettings.mPackages.valueAt(i);
19689             boolean pkgGrantsKnown = false;
19690
19691             PermissionsState packagePerms = ps.getPermissionsState();
19692
19693             for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19694                 final int grantFlags = state.getFlags();
19695                 // only look at grants that are not system/policy fixed
19696                 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19697                     final boolean isGranted = state.isGranted();
19698                     // And only back up the user-twiddled state bits
19699                     if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19700                         final String packageName = mSettings.mPackages.keyAt(i);
19701                         if (!pkgGrantsKnown) {
19702                             serializer.startTag(null, TAG_GRANT);
19703                             serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19704                             pkgGrantsKnown = true;
19705                         }
19706
19707                         final boolean userSet =
19708                                 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19709                         final boolean userFixed =
19710                                 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19711                         final boolean revoke =
19712                                 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19713
19714                         serializer.startTag(null, TAG_PERMISSION);
19715                         serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19716                         if (isGranted) {
19717                             serializer.attribute(null, ATTR_IS_GRANTED, "true");
19718                         }
19719                         if (userSet) {
19720                             serializer.attribute(null, ATTR_USER_SET, "true");
19721                         }
19722                         if (userFixed) {
19723                             serializer.attribute(null, ATTR_USER_FIXED, "true");
19724                         }
19725                         if (revoke) {
19726                             serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19727                         }
19728                         serializer.endTag(null, TAG_PERMISSION);
19729                     }
19730                 }
19731             }
19732
19733             if (pkgGrantsKnown) {
19734                 serializer.endTag(null, TAG_GRANT);
19735             }
19736         }
19737
19738         serializer.endTag(null, TAG_ALL_GRANTS);
19739     }
19740
19741     private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19742             throws XmlPullParserException, IOException {
19743         String pkgName = null;
19744         int outerDepth = parser.getDepth();
19745         int type;
19746         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19747                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19748             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19749                 continue;
19750             }
19751
19752             final String tagName = parser.getName();
19753             if (tagName.equals(TAG_GRANT)) {
19754                 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19755                 if (DEBUG_BACKUP) {
19756                     Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19757                 }
19758             } else if (tagName.equals(TAG_PERMISSION)) {
19759
19760                 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19761                 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19762
19763                 int newFlagSet = 0;
19764                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19765                     newFlagSet |= FLAG_PERMISSION_USER_SET;
19766                 }
19767                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19768                     newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19769                 }
19770                 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19771                     newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19772                 }
19773                 if (DEBUG_BACKUP) {
19774                     Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
19775                             + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
19776                 }
19777                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
19778                 if (ps != null) {
19779                     // Already installed so we apply the grant immediately
19780                     if (DEBUG_BACKUP) {
19781                         Slog.v(TAG, "        + already installed; applying");
19782                     }
19783                     PermissionsState perms = ps.getPermissionsState();
19784                     BasePermission bp = mSettings.mPermissions.get(permName);
19785                     if (bp != null) {
19786                         if (isGranted) {
19787                             perms.grantRuntimePermission(bp, userId);
19788                         }
19789                         if (newFlagSet != 0) {
19790                             perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19791                         }
19792                     }
19793                 } else {
19794                     // Need to wait for post-restore install to apply the grant
19795                     if (DEBUG_BACKUP) {
19796                         Slog.v(TAG, "        - not yet installed; saving for later");
19797                     }
19798                     mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19799                             isGranted, newFlagSet, userId);
19800                 }
19801             } else {
19802                 PackageManagerService.reportSettingsProblem(Log.WARN,
19803                         "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19804                 XmlUtils.skipCurrentTag(parser);
19805             }
19806         }
19807
19808         scheduleWriteSettingsLocked();
19809         mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19810     }
19811
19812     @Override
19813     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19814             int sourceUserId, int targetUserId, int flags) {
19815         mContext.enforceCallingOrSelfPermission(
19816                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19817         int callingUid = Binder.getCallingUid();
19818         enforceOwnerRights(ownerPackage, callingUid);
19819         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19820         if (intentFilter.countActions() == 0) {
19821             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19822             return;
19823         }
19824         synchronized (mPackages) {
19825             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19826                     ownerPackage, targetUserId, flags);
19827             CrossProfileIntentResolver resolver =
19828                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19829             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19830             // We have all those whose filter is equal. Now checking if the rest is equal as well.
19831             if (existing != null) {
19832                 int size = existing.size();
19833                 for (int i = 0; i < size; i++) {
19834                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19835                         return;
19836                     }
19837                 }
19838             }
19839             resolver.addFilter(newFilter);
19840             scheduleWritePackageRestrictionsLocked(sourceUserId);
19841         }
19842     }
19843
19844     @Override
19845     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19846         mContext.enforceCallingOrSelfPermission(
19847                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19848         int callingUid = Binder.getCallingUid();
19849         enforceOwnerRights(ownerPackage, callingUid);
19850         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19851         synchronized (mPackages) {
19852             CrossProfileIntentResolver resolver =
19853                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19854             ArraySet<CrossProfileIntentFilter> set =
19855                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19856             for (CrossProfileIntentFilter filter : set) {
19857                 if (filter.getOwnerPackage().equals(ownerPackage)) {
19858                     resolver.removeFilter(filter);
19859                 }
19860             }
19861             scheduleWritePackageRestrictionsLocked(sourceUserId);
19862         }
19863     }
19864
19865     // Enforcing that callingUid is owning pkg on userId
19866     private void enforceOwnerRights(String pkg, int callingUid) {
19867         // The system owns everything.
19868         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19869             return;
19870         }
19871         int callingUserId = UserHandle.getUserId(callingUid);
19872         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19873         if (pi == null) {
19874             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19875                     + callingUserId);
19876         }
19877         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19878             throw new SecurityException("Calling uid " + callingUid
19879                     + " does not own package " + pkg);
19880         }
19881     }
19882
19883     @Override
19884     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19885         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19886     }
19887
19888     /**
19889      * Report the 'Home' activity which is currently set as "always use this one". If non is set
19890      * then reports the most likely home activity or null if there are more than one.
19891      */
19892     public ComponentName getDefaultHomeActivity(int userId) {
19893         List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19894         ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19895         if (cn != null) {
19896             return cn;
19897         }
19898
19899         // Find the launcher with the highest priority and return that component if there are no
19900         // other home activity with the same priority.
19901         int lastPriority = Integer.MIN_VALUE;
19902         ComponentName lastComponent = null;
19903         final int size = allHomeCandidates.size();
19904         for (int i = 0; i < size; i++) {
19905             final ResolveInfo ri = allHomeCandidates.get(i);
19906             if (ri.priority > lastPriority) {
19907                 lastComponent = ri.activityInfo.getComponentName();
19908                 lastPriority = ri.priority;
19909             } else if (ri.priority == lastPriority) {
19910                 // Two components found with same priority.
19911                 lastComponent = null;
19912             }
19913         }
19914         return lastComponent;
19915     }
19916
19917     private Intent getHomeIntent() {
19918         Intent intent = new Intent(Intent.ACTION_MAIN);
19919         intent.addCategory(Intent.CATEGORY_HOME);
19920         intent.addCategory(Intent.CATEGORY_DEFAULT);
19921         return intent;
19922     }
19923
19924     private IntentFilter getHomeFilter() {
19925         IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19926         filter.addCategory(Intent.CATEGORY_HOME);
19927         filter.addCategory(Intent.CATEGORY_DEFAULT);
19928         return filter;
19929     }
19930
19931     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19932             int userId) {
19933         Intent intent  = getHomeIntent();
19934         List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19935                 PackageManager.GET_META_DATA, userId);
19936         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19937                 true, false, false, userId);
19938
19939         allHomeCandidates.clear();
19940         if (list != null) {
19941             for (ResolveInfo ri : list) {
19942                 allHomeCandidates.add(ri);
19943             }
19944         }
19945         return (preferred == null || preferred.activityInfo == null)
19946                 ? null
19947                 : new ComponentName(preferred.activityInfo.packageName,
19948                         preferred.activityInfo.name);
19949     }
19950
19951     @Override
19952     public void setHomeActivity(ComponentName comp, int userId) {
19953         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19954         getHomeActivitiesAsUser(homeActivities, userId);
19955
19956         boolean found = false;
19957
19958         final int size = homeActivities.size();
19959         final ComponentName[] set = new ComponentName[size];
19960         for (int i = 0; i < size; i++) {
19961             final ResolveInfo candidate = homeActivities.get(i);
19962             final ActivityInfo info = candidate.activityInfo;
19963             final ComponentName activityName = new ComponentName(info.packageName, info.name);
19964             set[i] = activityName;
19965             if (!found && activityName.equals(comp)) {
19966                 found = true;
19967             }
19968         }
19969         if (!found) {
19970             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19971                     + userId);
19972         }
19973         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19974                 set, comp, userId);
19975     }
19976
19977     private @Nullable String getSetupWizardPackageName() {
19978         final Intent intent = new Intent(Intent.ACTION_MAIN);
19979         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19980
19981         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19982                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19983                         | MATCH_DISABLED_COMPONENTS,
19984                 UserHandle.myUserId());
19985         if (matches.size() == 1) {
19986             return matches.get(0).getComponentInfo().packageName;
19987         } else {
19988             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19989                     + ": matches=" + matches);
19990             return null;
19991         }
19992     }
19993
19994     private @Nullable String getStorageManagerPackageName() {
19995         final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19996
19997         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19998                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19999                         | MATCH_DISABLED_COMPONENTS,
20000                 UserHandle.myUserId());
20001         if (matches.size() == 1) {
20002             return matches.get(0).getComponentInfo().packageName;
20003         } else {
20004             Slog.e(TAG, "There should probably be exactly one storage manager; found "
20005                     + matches.size() + ": matches=" + matches);
20006             return null;
20007         }
20008     }
20009
20010     @Override
20011     public void setApplicationEnabledSetting(String appPackageName,
20012             int newState, int flags, int userId, String callingPackage) {
20013         if (!sUserManager.exists(userId)) return;
20014         if (callingPackage == null) {
20015             callingPackage = Integer.toString(Binder.getCallingUid());
20016         }
20017         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20018     }
20019
20020     @Override
20021     public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20022         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20023         synchronized (mPackages) {
20024             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20025             if (pkgSetting != null) {
20026                 pkgSetting.setUpdateAvailable(updateAvailable);
20027             }
20028         }
20029     }
20030
20031     @Override
20032     public void setComponentEnabledSetting(ComponentName componentName,
20033             int newState, int flags, int userId) {
20034         if (!sUserManager.exists(userId)) return;
20035         setEnabledSetting(componentName.getPackageName(),
20036                 componentName.getClassName(), newState, flags, userId, null);
20037     }
20038
20039     private void setEnabledSetting(final String packageName, String className, int newState,
20040             final int flags, int userId, String callingPackage) {
20041         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20042               || newState == COMPONENT_ENABLED_STATE_ENABLED
20043               || newState == COMPONENT_ENABLED_STATE_DISABLED
20044               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20045               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20046             throw new IllegalArgumentException("Invalid new component state: "
20047                     + newState);
20048         }
20049         PackageSetting pkgSetting;
20050         final int uid = Binder.getCallingUid();
20051         final int permission;
20052         if (uid == Process.SYSTEM_UID) {
20053             permission = PackageManager.PERMISSION_GRANTED;
20054         } else {
20055             permission = mContext.checkCallingOrSelfPermission(
20056                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20057         }
20058         enforceCrossUserPermission(uid, userId,
20059                 false /* requireFullPermission */, true /* checkShell */, "set enabled");
20060         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20061         boolean sendNow = false;
20062         boolean isApp = (className == null);
20063         String componentName = isApp ? packageName : className;
20064         int packageUid = -1;
20065         ArrayList<String> components;
20066
20067         // writer
20068         synchronized (mPackages) {
20069             pkgSetting = mSettings.mPackages.get(packageName);
20070             if (pkgSetting == null) {
20071                 if (className == null) {
20072                     throw new IllegalArgumentException("Unknown package: " + packageName);
20073                 }
20074                 throw new IllegalArgumentException(
20075                         "Unknown component: " + packageName + "/" + className);
20076             }
20077         }
20078
20079         // Limit who can change which apps
20080         if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
20081             // Don't allow apps that don't have permission to modify other apps
20082             if (!allowedByPermission) {
20083                 throw new SecurityException(
20084                         "Permission Denial: attempt to change component state from pid="
20085                         + Binder.getCallingPid()
20086                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
20087             }
20088             // Don't allow changing protected packages.
20089             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20090                 throw new SecurityException("Cannot disable a protected package: " + packageName);
20091             }
20092         }
20093
20094         synchronized (mPackages) {
20095             if (uid == Process.SHELL_UID
20096                     && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20097                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
20098                 // unless it is a test package.
20099                 int oldState = pkgSetting.getEnabled(userId);
20100                 if (className == null
20101                     &&
20102                     (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20103                      || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20104                      || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20105                     &&
20106                     (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20107                      || newState == COMPONENT_ENABLED_STATE_DEFAULT
20108                      || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20109                     // ok
20110                 } else {
20111                     throw new SecurityException(
20112                             "Shell cannot change component state for " + packageName + "/"
20113                             + className + " to " + newState);
20114                 }
20115             }
20116             if (className == null) {
20117                 // We're dealing with an application/package level state change
20118                 if (pkgSetting.getEnabled(userId) == newState) {
20119                     // Nothing to do
20120                     return;
20121                 }
20122                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20123                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20124                     // Don't care about who enables an app.
20125                     callingPackage = null;
20126                 }
20127                 pkgSetting.setEnabled(newState, userId, callingPackage);
20128                 // pkgSetting.pkg.mSetEnabled = newState;
20129             } else {
20130                 // We're dealing with a component level state change
20131                 // First, verify that this is a valid class name.
20132                 PackageParser.Package pkg = pkgSetting.pkg;
20133                 if (pkg == null || !pkg.hasComponentClassName(className)) {
20134                     if (pkg != null &&
20135                             pkg.applicationInfo.targetSdkVersion >=
20136                                     Build.VERSION_CODES.JELLY_BEAN) {
20137                         throw new IllegalArgumentException("Component class " + className
20138                                 + " does not exist in " + packageName);
20139                     } else {
20140                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20141                                 + className + " does not exist in " + packageName);
20142                     }
20143                 }
20144                 switch (newState) {
20145                 case COMPONENT_ENABLED_STATE_ENABLED:
20146                     if (!pkgSetting.enableComponentLPw(className, userId)) {
20147                         return;
20148                     }
20149                     break;
20150                 case COMPONENT_ENABLED_STATE_DISABLED:
20151                     if (!pkgSetting.disableComponentLPw(className, userId)) {
20152                         return;
20153                     }
20154                     break;
20155                 case COMPONENT_ENABLED_STATE_DEFAULT:
20156                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
20157                         return;
20158                     }
20159                     break;
20160                 default:
20161                     Slog.e(TAG, "Invalid new component state: " + newState);
20162                     return;
20163                 }
20164             }
20165             scheduleWritePackageRestrictionsLocked(userId);
20166             updateSequenceNumberLP(packageName, new int[] { userId });
20167             final long callingId = Binder.clearCallingIdentity();
20168             try {
20169                 updateInstantAppInstallerLocked(packageName);
20170             } finally {
20171                 Binder.restoreCallingIdentity(callingId);
20172             }
20173             components = mPendingBroadcasts.get(userId, packageName);
20174             final boolean newPackage = components == null;
20175             if (newPackage) {
20176                 components = new ArrayList<String>();
20177             }
20178             if (!components.contains(componentName)) {
20179                 components.add(componentName);
20180             }
20181             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20182                 sendNow = true;
20183                 // Purge entry from pending broadcast list if another one exists already
20184                 // since we are sending one right away.
20185                 mPendingBroadcasts.remove(userId, packageName);
20186             } else {
20187                 if (newPackage) {
20188                     mPendingBroadcasts.put(userId, packageName, components);
20189                 }
20190                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20191                     // Schedule a message
20192                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20193                 }
20194             }
20195         }
20196
20197         long callingId = Binder.clearCallingIdentity();
20198         try {
20199             if (sendNow) {
20200                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20201                 sendPackageChangedBroadcast(packageName,
20202                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20203             }
20204         } finally {
20205             Binder.restoreCallingIdentity(callingId);
20206         }
20207     }
20208
20209     @Override
20210     public void flushPackageRestrictionsAsUser(int userId) {
20211         if (!sUserManager.exists(userId)) {
20212             return;
20213         }
20214         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20215                 false /* checkShell */, "flushPackageRestrictions");
20216         synchronized (mPackages) {
20217             mSettings.writePackageRestrictionsLPr(userId);
20218             mDirtyUsers.remove(userId);
20219             if (mDirtyUsers.isEmpty()) {
20220                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20221             }
20222         }
20223     }
20224
20225     private void sendPackageChangedBroadcast(String packageName,
20226             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20227         if (DEBUG_INSTALL)
20228             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20229                     + componentNames);
20230         Bundle extras = new Bundle(4);
20231         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20232         String nameList[] = new String[componentNames.size()];
20233         componentNames.toArray(nameList);
20234         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20235         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20236         extras.putInt(Intent.EXTRA_UID, packageUid);
20237         // If this is not reporting a change of the overall package, then only send it
20238         // to registered receivers.  We don't want to launch a swath of apps for every
20239         // little component state change.
20240         final int flags = !componentNames.contains(packageName)
20241                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20242         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20243                 new int[] {UserHandle.getUserId(packageUid)});
20244     }
20245
20246     @Override
20247     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20248         if (!sUserManager.exists(userId)) return;
20249         final int uid = Binder.getCallingUid();
20250         final int permission = mContext.checkCallingOrSelfPermission(
20251                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20252         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20253         enforceCrossUserPermission(uid, userId,
20254                 true /* requireFullPermission */, true /* checkShell */, "stop package");
20255         // writer
20256         synchronized (mPackages) {
20257             if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20258                     allowedByPermission, uid, userId)) {
20259                 scheduleWritePackageRestrictionsLocked(userId);
20260             }
20261         }
20262     }
20263
20264     @Override
20265     public String getInstallerPackageName(String packageName) {
20266         // reader
20267         synchronized (mPackages) {
20268             return mSettings.getInstallerPackageNameLPr(packageName);
20269         }
20270     }
20271
20272     public boolean isOrphaned(String packageName) {
20273         // reader
20274         synchronized (mPackages) {
20275             return mSettings.isOrphaned(packageName);
20276         }
20277     }
20278
20279     @Override
20280     public int getApplicationEnabledSetting(String packageName, int userId) {
20281         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20282         int uid = Binder.getCallingUid();
20283         enforceCrossUserPermission(uid, userId,
20284                 false /* requireFullPermission */, false /* checkShell */, "get enabled");
20285         // reader
20286         synchronized (mPackages) {
20287             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20288         }
20289     }
20290
20291     @Override
20292     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
20293         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20294         int uid = Binder.getCallingUid();
20295         enforceCrossUserPermission(uid, userId,
20296                 false /* requireFullPermission */, false /* checkShell */, "get component enabled");
20297         // reader
20298         synchronized (mPackages) {
20299             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
20300         }
20301     }
20302
20303     @Override
20304     public void enterSafeMode() {
20305         enforceSystemOrRoot("Only the system can request entering safe mode");
20306
20307         if (!mSystemReady) {
20308             mSafeMode = true;
20309         }
20310     }
20311
20312     @Override
20313     public void systemReady() {
20314         mSystemReady = true;
20315         final ContentResolver resolver = mContext.getContentResolver();
20316         ContentObserver co = new ContentObserver(mHandler) {
20317             @Override
20318             public void onChange(boolean selfChange) {
20319                 mEphemeralAppsDisabled =
20320                         (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20321                                 (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20322             }
20323         };
20324         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20325                         .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20326                 false, co, UserHandle.USER_SYSTEM);
20327         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20328                         .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20329         co.onChange(true);
20330
20331         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20332         // disabled after already being started.
20333         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20334                 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20335
20336         // Read the compatibilty setting when the system is ready.
20337         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20338                 mContext.getContentResolver(),
20339                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20340         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20341         if (DEBUG_SETTINGS) {
20342             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20343         }
20344
20345         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20346
20347         synchronized (mPackages) {
20348             // Verify that all of the preferred activity components actually
20349             // exist.  It is possible for applications to be updated and at
20350             // that point remove a previously declared activity component that
20351             // had been set as a preferred activity.  We try to clean this up
20352             // the next time we encounter that preferred activity, but it is
20353             // possible for the user flow to never be able to return to that
20354             // situation so here we do a sanity check to make sure we haven't
20355             // left any junk around.
20356             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20357             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20358                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20359                 removed.clear();
20360                 for (PreferredActivity pa : pir.filterSet()) {
20361                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20362                         removed.add(pa);
20363                     }
20364                 }
20365                 if (removed.size() > 0) {
20366                     for (int r=0; r<removed.size(); r++) {
20367                         PreferredActivity pa = removed.get(r);
20368                         Slog.w(TAG, "Removing dangling preferred activity: "
20369                                 + pa.mPref.mComponent);
20370                         pir.removeFilter(pa);
20371                     }
20372                     mSettings.writePackageRestrictionsLPr(
20373                             mSettings.mPreferredActivities.keyAt(i));
20374                 }
20375             }
20376
20377             for (int userId : UserManagerService.getInstance().getUserIds()) {
20378                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20379                     grantPermissionsUserIds = ArrayUtils.appendInt(
20380                             grantPermissionsUserIds, userId);
20381                 }
20382             }
20383         }
20384         sUserManager.systemReady();
20385
20386         // If we upgraded grant all default permissions before kicking off.
20387         for (int userId : grantPermissionsUserIds) {
20388             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20389         }
20390
20391         // If we did not grant default permissions, we preload from this the
20392         // default permission exceptions lazily to ensure we don't hit the
20393         // disk on a new user creation.
20394         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20395             mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20396         }
20397
20398         // Kick off any messages waiting for system ready
20399         if (mPostSystemReadyMessages != null) {
20400             for (Message msg : mPostSystemReadyMessages) {
20401                 msg.sendToTarget();
20402             }
20403             mPostSystemReadyMessages = null;
20404         }
20405
20406         // Watch for external volumes that come and go over time
20407         final StorageManager storage = mContext.getSystemService(StorageManager.class);
20408         storage.registerListener(mStorageListener);
20409
20410         mInstallerService.systemReady();
20411         mPackageDexOptimizer.systemReady();
20412
20413         StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20414                 StorageManagerInternal.class);
20415         StorageManagerInternal.addExternalStoragePolicy(
20416                 new StorageManagerInternal.ExternalStorageMountPolicy() {
20417             @Override
20418             public int getMountMode(int uid, String packageName) {
20419                 if (Process.isIsolated(uid)) {
20420                     return Zygote.MOUNT_EXTERNAL_NONE;
20421                 }
20422                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20423                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
20424                 }
20425                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20426                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
20427                 }
20428                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20429                     return Zygote.MOUNT_EXTERNAL_READ;
20430                 }
20431                 return Zygote.MOUNT_EXTERNAL_WRITE;
20432             }
20433
20434             @Override
20435             public boolean hasExternalStorage(int uid, String packageName) {
20436                 return true;
20437             }
20438         });
20439
20440         // Now that we're mostly running, clean up stale users and apps
20441         sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20442         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20443
20444         if (mPrivappPermissionsViolations != null) {
20445             Slog.wtf(TAG,"Signature|privileged permissions not in "
20446                     + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
20447             mPrivappPermissionsViolations = null;
20448         }
20449     }
20450
20451     public void waitForAppDataPrepared() {
20452         if (mPrepareAppDataFuture == null) {
20453             return;
20454         }
20455         ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20456         mPrepareAppDataFuture = null;
20457     }
20458
20459     @Override
20460     public boolean isSafeMode() {
20461         return mSafeMode;
20462     }
20463
20464     @Override
20465     public boolean hasSystemUidErrors() {
20466         return mHasSystemUidErrors;
20467     }
20468
20469     static String arrayToString(int[] array) {
20470         StringBuffer buf = new StringBuffer(128);
20471         buf.append('[');
20472         if (array != null) {
20473             for (int i=0; i<array.length; i++) {
20474                 if (i > 0) buf.append(", ");
20475                 buf.append(array[i]);
20476             }
20477         }
20478         buf.append(']');
20479         return buf.toString();
20480     }
20481
20482     static class DumpState {
20483         public static final int DUMP_LIBS = 1 << 0;
20484         public static final int DUMP_FEATURES = 1 << 1;
20485         public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20486         public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20487         public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20488         public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20489         public static final int DUMP_PERMISSIONS = 1 << 6;
20490         public static final int DUMP_PACKAGES = 1 << 7;
20491         public static final int DUMP_SHARED_USERS = 1 << 8;
20492         public static final int DUMP_MESSAGES = 1 << 9;
20493         public static final int DUMP_PROVIDERS = 1 << 10;
20494         public static final int DUMP_VERIFIERS = 1 << 11;
20495         public static final int DUMP_PREFERRED = 1 << 12;
20496         public static final int DUMP_PREFERRED_XML = 1 << 13;
20497         public static final int DUMP_KEYSETS = 1 << 14;
20498         public static final int DUMP_VERSION = 1 << 15;
20499         public static final int DUMP_INSTALLS = 1 << 16;
20500         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20501         public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20502         public static final int DUMP_FROZEN = 1 << 19;
20503         public static final int DUMP_DEXOPT = 1 << 20;
20504         public static final int DUMP_COMPILER_STATS = 1 << 21;
20505         public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
20506
20507         public static final int OPTION_SHOW_FILTERS = 1 << 0;
20508
20509         private int mTypes;
20510
20511         private int mOptions;
20512
20513         private boolean mTitlePrinted;
20514
20515         private SharedUserSetting mSharedUser;
20516
20517         public boolean isDumping(int type) {
20518             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20519                 return true;
20520             }
20521
20522             return (mTypes & type) != 0;
20523         }
20524
20525         public void setDump(int type) {
20526             mTypes |= type;
20527         }
20528
20529         public boolean isOptionEnabled(int option) {
20530             return (mOptions & option) != 0;
20531         }
20532
20533         public void setOptionEnabled(int option) {
20534             mOptions |= option;
20535         }
20536
20537         public boolean onTitlePrinted() {
20538             final boolean printed = mTitlePrinted;
20539             mTitlePrinted = true;
20540             return printed;
20541         }
20542
20543         public boolean getTitlePrinted() {
20544             return mTitlePrinted;
20545         }
20546
20547         public void setTitlePrinted(boolean enabled) {
20548             mTitlePrinted = enabled;
20549         }
20550
20551         public SharedUserSetting getSharedUser() {
20552             return mSharedUser;
20553         }
20554
20555         public void setSharedUser(SharedUserSetting user) {
20556             mSharedUser = user;
20557         }
20558     }
20559
20560     @Override
20561     public void onShellCommand(FileDescriptor in, FileDescriptor out,
20562             FileDescriptor err, String[] args, ShellCallback callback,
20563             ResultReceiver resultReceiver) {
20564         (new PackageManagerShellCommand(this)).exec(
20565                 this, in, out, err, args, callback, resultReceiver);
20566     }
20567
20568     @Override
20569     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20570         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20571
20572         DumpState dumpState = new DumpState();
20573         boolean fullPreferred = false;
20574         boolean checkin = false;
20575
20576         String packageName = null;
20577         ArraySet<String> permissionNames = null;
20578
20579         int opti = 0;
20580         while (opti < args.length) {
20581             String opt = args[opti];
20582             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20583                 break;
20584             }
20585             opti++;
20586
20587             if ("-a".equals(opt)) {
20588                 // Right now we only know how to print all.
20589             } else if ("-h".equals(opt)) {
20590                 pw.println("Package manager dump options:");
20591                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20592                 pw.println("    --checkin: dump for a checkin");
20593                 pw.println("    -f: print details of intent filters");
20594                 pw.println("    -h: print this help");
20595                 pw.println("  cmd may be one of:");
20596                 pw.println("    l[ibraries]: list known shared libraries");
20597                 pw.println("    f[eatures]: list device features");
20598                 pw.println("    k[eysets]: print known keysets");
20599                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20600                 pw.println("    perm[issions]: dump permissions");
20601                 pw.println("    permission [name ...]: dump declaration and use of given permission");
20602                 pw.println("    pref[erred]: print preferred package settings");
20603                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20604                 pw.println("    prov[iders]: dump content providers");
20605                 pw.println("    p[ackages]: dump installed packages");
20606                 pw.println("    s[hared-users]: dump shared user IDs");
20607                 pw.println("    m[essages]: print collected runtime messages");
20608                 pw.println("    v[erifiers]: print package verifier info");
20609                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20610                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20611                 pw.println("    version: print database version info");
20612                 pw.println("    write: write current settings now");
20613                 pw.println("    installs: details about install sessions");
20614                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20615                 pw.println("    dexopt: dump dexopt state");
20616                 pw.println("    compiler-stats: dump compiler statistics");
20617                 pw.println("    enabled-overlays: dump list of enabled overlay packages");
20618                 pw.println("    <package.name>: info about given package");
20619                 return;
20620             } else if ("--checkin".equals(opt)) {
20621                 checkin = true;
20622             } else if ("-f".equals(opt)) {
20623                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20624             } else if ("--proto".equals(opt)) {
20625                 dumpProto(fd);
20626                 return;
20627             } else {
20628                 pw.println("Unknown argument: " + opt + "; use -h for help");
20629             }
20630         }
20631
20632         // Is the caller requesting to dump a particular piece of data?
20633         if (opti < args.length) {
20634             String cmd = args[opti];
20635             opti++;
20636             // Is this a package name?
20637             if ("android".equals(cmd) || cmd.contains(".")) {
20638                 packageName = cmd;
20639                 // When dumping a single package, we always dump all of its
20640                 // filter information since the amount of data will be reasonable.
20641                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20642             } else if ("check-permission".equals(cmd)) {
20643                 if (opti >= args.length) {
20644                     pw.println("Error: check-permission missing permission argument");
20645                     return;
20646                 }
20647                 String perm = args[opti];
20648                 opti++;
20649                 if (opti >= args.length) {
20650                     pw.println("Error: check-permission missing package argument");
20651                     return;
20652                 }
20653
20654                 String pkg = args[opti];
20655                 opti++;
20656                 int user = UserHandle.getUserId(Binder.getCallingUid());
20657                 if (opti < args.length) {
20658                     try {
20659                         user = Integer.parseInt(args[opti]);
20660                     } catch (NumberFormatException e) {
20661                         pw.println("Error: check-permission user argument is not a number: "
20662                                 + args[opti]);
20663                         return;
20664                     }
20665                 }
20666
20667                 // Normalize package name to handle renamed packages and static libs
20668                 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20669
20670                 pw.println(checkPermission(perm, pkg, user));
20671                 return;
20672             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20673                 dumpState.setDump(DumpState.DUMP_LIBS);
20674             } else if ("f".equals(cmd) || "features".equals(cmd)) {
20675                 dumpState.setDump(DumpState.DUMP_FEATURES);
20676             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20677                 if (opti >= args.length) {
20678                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20679                             | DumpState.DUMP_SERVICE_RESOLVERS
20680                             | DumpState.DUMP_RECEIVER_RESOLVERS
20681                             | DumpState.DUMP_CONTENT_RESOLVERS);
20682                 } else {
20683                     while (opti < args.length) {
20684                         String name = args[opti];
20685                         if ("a".equals(name) || "activity".equals(name)) {
20686                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20687                         } else if ("s".equals(name) || "service".equals(name)) {
20688                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20689                         } else if ("r".equals(name) || "receiver".equals(name)) {
20690                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20691                         } else if ("c".equals(name) || "content".equals(name)) {
20692                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20693                         } else {
20694                             pw.println("Error: unknown resolver table type: " + name);
20695                             return;
20696                         }
20697                         opti++;
20698                     }
20699                 }
20700             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20701                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20702             } else if ("permission".equals(cmd)) {
20703                 if (opti >= args.length) {
20704                     pw.println("Error: permission requires permission name");
20705                     return;
20706                 }
20707                 permissionNames = new ArraySet<>();
20708                 while (opti < args.length) {
20709                     permissionNames.add(args[opti]);
20710                     opti++;
20711                 }
20712                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
20713                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20714             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20715                 dumpState.setDump(DumpState.DUMP_PREFERRED);
20716             } else if ("preferred-xml".equals(cmd)) {
20717                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20718                 if (opti < args.length && "--full".equals(args[opti])) {
20719                     fullPreferred = true;
20720                     opti++;
20721                 }
20722             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20723                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20724             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20725                 dumpState.setDump(DumpState.DUMP_PACKAGES);
20726             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20727                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20728             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20729                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
20730             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20731                 dumpState.setDump(DumpState.DUMP_MESSAGES);
20732             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20733                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
20734             } else if ("i".equals(cmd) || "ifv".equals(cmd)
20735                     || "intent-filter-verifiers".equals(cmd)) {
20736                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20737             } else if ("version".equals(cmd)) {
20738                 dumpState.setDump(DumpState.DUMP_VERSION);
20739             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20740                 dumpState.setDump(DumpState.DUMP_KEYSETS);
20741             } else if ("installs".equals(cmd)) {
20742                 dumpState.setDump(DumpState.DUMP_INSTALLS);
20743             } else if ("frozen".equals(cmd)) {
20744                 dumpState.setDump(DumpState.DUMP_FROZEN);
20745             } else if ("dexopt".equals(cmd)) {
20746                 dumpState.setDump(DumpState.DUMP_DEXOPT);
20747             } else if ("compiler-stats".equals(cmd)) {
20748                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20749             } else if ("enabled-overlays".equals(cmd)) {
20750                 dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
20751             } else if ("write".equals(cmd)) {
20752                 synchronized (mPackages) {
20753                     mSettings.writeLPr();
20754                     pw.println("Settings written.");
20755                     return;
20756                 }
20757             }
20758         }
20759
20760         if (checkin) {
20761             pw.println("vers,1");
20762         }
20763
20764         // reader
20765         synchronized (mPackages) {
20766             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20767                 if (!checkin) {
20768                     if (dumpState.onTitlePrinted())
20769                         pw.println();
20770                     pw.println("Database versions:");
20771                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20772                 }
20773             }
20774
20775             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20776                 if (!checkin) {
20777                     if (dumpState.onTitlePrinted())
20778                         pw.println();
20779                     pw.println("Verifiers:");
20780                     pw.print("  Required: ");
20781                     pw.print(mRequiredVerifierPackage);
20782                     pw.print(" (uid=");
20783                     pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20784                             UserHandle.USER_SYSTEM));
20785                     pw.println(")");
20786                 } else if (mRequiredVerifierPackage != null) {
20787                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20788                     pw.print(",");
20789                     pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20790                             UserHandle.USER_SYSTEM));
20791                 }
20792             }
20793
20794             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20795                     packageName == null) {
20796                 if (mIntentFilterVerifierComponent != null) {
20797                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20798                     if (!checkin) {
20799                         if (dumpState.onTitlePrinted())
20800                             pw.println();
20801                         pw.println("Intent Filter Verifier:");
20802                         pw.print("  Using: ");
20803                         pw.print(verifierPackageName);
20804                         pw.print(" (uid=");
20805                         pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20806                                 UserHandle.USER_SYSTEM));
20807                         pw.println(")");
20808                     } else if (verifierPackageName != null) {
20809                         pw.print("ifv,"); pw.print(verifierPackageName);
20810                         pw.print(",");
20811                         pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20812                                 UserHandle.USER_SYSTEM));
20813                     }
20814                 } else {
20815                     pw.println();
20816                     pw.println("No Intent Filter Verifier available!");
20817                 }
20818             }
20819
20820             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20821                 boolean printedHeader = false;
20822                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
20823                 while (it.hasNext()) {
20824                     String libName = it.next();
20825                     SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20826                     if (versionedLib == null) {
20827                         continue;
20828                     }
20829                     final int versionCount = versionedLib.size();
20830                     for (int i = 0; i < versionCount; i++) {
20831                         SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20832                         if (!checkin) {
20833                             if (!printedHeader) {
20834                                 if (dumpState.onTitlePrinted())
20835                                     pw.println();
20836                                 pw.println("Libraries:");
20837                                 printedHeader = true;
20838                             }
20839                             pw.print("  ");
20840                         } else {
20841                             pw.print("lib,");
20842                         }
20843                         pw.print(libEntry.info.getName());
20844                         if (libEntry.info.isStatic()) {
20845                             pw.print(" version=" + libEntry.info.getVersion());
20846                         }
20847                         if (!checkin) {
20848                             pw.print(" -> ");
20849                         }
20850                         if (libEntry.path != null) {
20851                             pw.print(" (jar) ");
20852                             pw.print(libEntry.path);
20853                         } else {
20854                             pw.print(" (apk) ");
20855                             pw.print(libEntry.apk);
20856                         }
20857                         pw.println();
20858                     }
20859                 }
20860             }
20861
20862             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20863                 if (dumpState.onTitlePrinted())
20864                     pw.println();
20865                 if (!checkin) {
20866                     pw.println("Features:");
20867                 }
20868
20869                 synchronized (mAvailableFeatures) {
20870                     for (FeatureInfo feat : mAvailableFeatures.values()) {
20871                         if (checkin) {
20872                             pw.print("feat,");
20873                             pw.print(feat.name);
20874                             pw.print(",");
20875                             pw.println(feat.version);
20876                         } else {
20877                             pw.print("  ");
20878                             pw.print(feat.name);
20879                             if (feat.version > 0) {
20880                                 pw.print(" version=");
20881                                 pw.print(feat.version);
20882                             }
20883                             pw.println();
20884                         }
20885                     }
20886                 }
20887             }
20888
20889             if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20890                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20891                         : "Activity Resolver Table:", "  ", packageName,
20892                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20893                     dumpState.setTitlePrinted(true);
20894                 }
20895             }
20896             if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20897                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20898                         : "Receiver Resolver Table:", "  ", packageName,
20899                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20900                     dumpState.setTitlePrinted(true);
20901                 }
20902             }
20903             if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20904                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20905                         : "Service Resolver Table:", "  ", packageName,
20906                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20907                     dumpState.setTitlePrinted(true);
20908                 }
20909             }
20910             if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20911                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20912                         : "Provider Resolver Table:", "  ", packageName,
20913                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20914                     dumpState.setTitlePrinted(true);
20915                 }
20916             }
20917
20918             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20919                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20920                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20921                     int user = mSettings.mPreferredActivities.keyAt(i);
20922                     if (pir.dump(pw,
20923                             dumpState.getTitlePrinted()
20924                                 ? "\nPreferred Activities User " + user + ":"
20925                                 : "Preferred Activities User " + user + ":", "  ",
20926                             packageName, true, false)) {
20927                         dumpState.setTitlePrinted(true);
20928                     }
20929                 }
20930             }
20931
20932             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20933                 pw.flush();
20934                 FileOutputStream fout = new FileOutputStream(fd);
20935                 BufferedOutputStream str = new BufferedOutputStream(fout);
20936                 XmlSerializer serializer = new FastXmlSerializer();
20937                 try {
20938                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
20939                     serializer.startDocument(null, true);
20940                     serializer.setFeature(
20941                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20942                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20943                     serializer.endDocument();
20944                     serializer.flush();
20945                 } catch (IllegalArgumentException e) {
20946                     pw.println("Failed writing: " + e);
20947                 } catch (IllegalStateException e) {
20948                     pw.println("Failed writing: " + e);
20949                 } catch (IOException e) {
20950                     pw.println("Failed writing: " + e);
20951                 }
20952             }
20953
20954             if (!checkin
20955                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20956                     && packageName == null) {
20957                 pw.println();
20958                 int count = mSettings.mPackages.size();
20959                 if (count == 0) {
20960                     pw.println("No applications!");
20961                     pw.println();
20962                 } else {
20963                     final String prefix = "  ";
20964                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20965                     if (allPackageSettings.size() == 0) {
20966                         pw.println("No domain preferred apps!");
20967                         pw.println();
20968                     } else {
20969                         pw.println("App verification status:");
20970                         pw.println();
20971                         count = 0;
20972                         for (PackageSetting ps : allPackageSettings) {
20973                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20974                             if (ivi == null || ivi.getPackageName() == null) continue;
20975                             pw.println(prefix + "Package: " + ivi.getPackageName());
20976                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
20977                             pw.println(prefix + "Status:  " + ivi.getStatusString());
20978                             pw.println();
20979                             count++;
20980                         }
20981                         if (count == 0) {
20982                             pw.println(prefix + "No app verification established.");
20983                             pw.println();
20984                         }
20985                         for (int userId : sUserManager.getUserIds()) {
20986                             pw.println("App linkages for user " + userId + ":");
20987                             pw.println();
20988                             count = 0;
20989                             for (PackageSetting ps : allPackageSettings) {
20990                                 final long status = ps.getDomainVerificationStatusForUser(userId);
20991                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20992                                         && !DEBUG_DOMAIN_VERIFICATION) {
20993                                     continue;
20994                                 }
20995                                 pw.println(prefix + "Package: " + ps.name);
20996                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20997                                 String statusStr = IntentFilterVerificationInfo.
20998                                         getStatusStringFromValue(status);
20999                                 pw.println(prefix + "Status:  " + statusStr);
21000                                 pw.println();
21001                                 count++;
21002                             }
21003                             if (count == 0) {
21004                                 pw.println(prefix + "No configured app linkages.");
21005                                 pw.println();
21006                             }
21007                         }
21008                     }
21009                 }
21010             }
21011
21012             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21013                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21014                 if (packageName == null && permissionNames == null) {
21015                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21016                         if (iperm == 0) {
21017                             if (dumpState.onTitlePrinted())
21018                                 pw.println();
21019                             pw.println("AppOp Permissions:");
21020                         }
21021                         pw.print("  AppOp Permission ");
21022                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
21023                         pw.println(":");
21024                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21025                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21026                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
21027                         }
21028                     }
21029                 }
21030             }
21031
21032             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21033                 boolean printedSomething = false;
21034                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
21035                     if (packageName != null && !packageName.equals(p.info.packageName)) {
21036                         continue;
21037                     }
21038                     if (!printedSomething) {
21039                         if (dumpState.onTitlePrinted())
21040                             pw.println();
21041                         pw.println("Registered ContentProviders:");
21042                         printedSomething = true;
21043                     }
21044                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21045                     pw.print("    "); pw.println(p.toString());
21046                 }
21047                 printedSomething = false;
21048                 for (Map.Entry<String, PackageParser.Provider> entry :
21049                         mProvidersByAuthority.entrySet()) {
21050                     PackageParser.Provider p = entry.getValue();
21051                     if (packageName != null && !packageName.equals(p.info.packageName)) {
21052                         continue;
21053                     }
21054                     if (!printedSomething) {
21055                         if (dumpState.onTitlePrinted())
21056                             pw.println();
21057                         pw.println("ContentProvider Authorities:");
21058                         printedSomething = true;
21059                     }
21060                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21061                     pw.print("    "); pw.println(p.toString());
21062                     if (p.info != null && p.info.applicationInfo != null) {
21063                         final String appInfo = p.info.applicationInfo.toString();
21064                         pw.print("      applicationInfo="); pw.println(appInfo);
21065                     }
21066                 }
21067             }
21068
21069             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21070                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21071             }
21072
21073             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21074                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21075             }
21076
21077             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21078                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21079             }
21080
21081             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21082                 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21083             }
21084
21085             if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21086                 // XXX should handle packageName != null by dumping only install data that
21087                 // the given package is involved with.
21088                 if (dumpState.onTitlePrinted()) pw.println();
21089
21090                 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21091                 ipw.println();
21092                 ipw.println("Frozen packages:");
21093                 ipw.increaseIndent();
21094                 if (mFrozenPackages.size() == 0) {
21095                     ipw.println("(none)");
21096                 } else {
21097                     for (int i = 0; i < mFrozenPackages.size(); i++) {
21098                         ipw.println(mFrozenPackages.valueAt(i));
21099                     }
21100                 }
21101                 ipw.decreaseIndent();
21102             }
21103
21104             if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21105                 if (dumpState.onTitlePrinted()) pw.println();
21106                 dumpDexoptStateLPr(pw, packageName);
21107             }
21108
21109             if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21110                 if (dumpState.onTitlePrinted()) pw.println();
21111                 dumpCompilerStatsLPr(pw, packageName);
21112             }
21113
21114             if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21115                 if (dumpState.onTitlePrinted()) pw.println();
21116                 dumpEnabledOverlaysLPr(pw);
21117             }
21118
21119             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21120                 if (dumpState.onTitlePrinted()) pw.println();
21121                 mSettings.dumpReadMessagesLPr(pw, dumpState);
21122
21123                 pw.println();
21124                 pw.println("Package warning messages:");
21125                 BufferedReader in = null;
21126                 String line = null;
21127                 try {
21128                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21129                     while ((line = in.readLine()) != null) {
21130                         if (line.contains("ignored: updated version")) continue;
21131                         pw.println(line);
21132                     }
21133                 } catch (IOException ignored) {
21134                 } finally {
21135                     IoUtils.closeQuietly(in);
21136                 }
21137             }
21138
21139             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21140                 BufferedReader in = null;
21141                 String line = null;
21142                 try {
21143                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21144                     while ((line = in.readLine()) != null) {
21145                         if (line.contains("ignored: updated version")) continue;
21146                         pw.print("msg,");
21147                         pw.println(line);
21148                     }
21149                 } catch (IOException ignored) {
21150                 } finally {
21151                     IoUtils.closeQuietly(in);
21152                 }
21153             }
21154         }
21155
21156         // PackageInstaller should be called outside of mPackages lock
21157         if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21158             // XXX should handle packageName != null by dumping only install data that
21159             // the given package is involved with.
21160             if (dumpState.onTitlePrinted()) pw.println();
21161             mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21162         }
21163     }
21164
21165     private void dumpProto(FileDescriptor fd) {
21166         final ProtoOutputStream proto = new ProtoOutputStream(fd);
21167
21168         synchronized (mPackages) {
21169             final long requiredVerifierPackageToken =
21170                     proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21171             proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21172             proto.write(
21173                     PackageServiceDumpProto.PackageShortProto.UID,
21174                     getPackageUid(
21175                             mRequiredVerifierPackage,
21176                             MATCH_DEBUG_TRIAGED_MISSING,
21177                             UserHandle.USER_SYSTEM));
21178             proto.end(requiredVerifierPackageToken);
21179
21180             if (mIntentFilterVerifierComponent != null) {
21181                 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21182                 final long verifierPackageToken =
21183                         proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21184                 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21185                 proto.write(
21186                         PackageServiceDumpProto.PackageShortProto.UID,
21187                         getPackageUid(
21188                                 verifierPackageName,
21189                                 MATCH_DEBUG_TRIAGED_MISSING,
21190                                 UserHandle.USER_SYSTEM));
21191                 proto.end(verifierPackageToken);
21192             }
21193
21194             dumpSharedLibrariesProto(proto);
21195             dumpFeaturesProto(proto);
21196             mSettings.dumpPackagesProto(proto);
21197             mSettings.dumpSharedUsersProto(proto);
21198             dumpMessagesProto(proto);
21199         }
21200         proto.flush();
21201     }
21202
21203     private void dumpMessagesProto(ProtoOutputStream proto) {
21204         BufferedReader in = null;
21205         String line = null;
21206         try {
21207             in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21208             while ((line = in.readLine()) != null) {
21209                 if (line.contains("ignored: updated version")) continue;
21210                 proto.write(PackageServiceDumpProto.MESSAGES, line);
21211             }
21212         } catch (IOException ignored) {
21213         } finally {
21214             IoUtils.closeQuietly(in);
21215         }
21216     }
21217
21218     private void dumpFeaturesProto(ProtoOutputStream proto) {
21219         synchronized (mAvailableFeatures) {
21220             final int count = mAvailableFeatures.size();
21221             for (int i = 0; i < count; i++) {
21222                 final FeatureInfo feat = mAvailableFeatures.valueAt(i);
21223                 final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
21224                 proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
21225                 proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
21226                 proto.end(featureToken);
21227             }
21228         }
21229     }
21230
21231     private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21232         final int count = mSharedLibraries.size();
21233         for (int i = 0; i < count; i++) {
21234             final String libName = mSharedLibraries.keyAt(i);
21235             SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21236             if (versionedLib == null) {
21237                 continue;
21238             }
21239             final int versionCount = versionedLib.size();
21240             for (int j = 0; j < versionCount; j++) {
21241                 final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21242                 final long sharedLibraryToken =
21243                         proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21244                 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21245                 final boolean isJar = (libEntry.path != null);
21246                 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21247                 if (isJar) {
21248                     proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21249                 } else {
21250                     proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21251                 }
21252                 proto.end(sharedLibraryToken);
21253             }
21254         }
21255     }
21256
21257     private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21258         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21259         ipw.println();
21260         ipw.println("Dexopt state:");
21261         ipw.increaseIndent();
21262         Collection<PackageParser.Package> packages = null;
21263         if (packageName != null) {
21264             PackageParser.Package targetPackage = mPackages.get(packageName);
21265             if (targetPackage != null) {
21266                 packages = Collections.singletonList(targetPackage);
21267             } else {
21268                 ipw.println("Unable to find package: " + packageName);
21269                 return;
21270             }
21271         } else {
21272             packages = mPackages.values();
21273         }
21274
21275         for (PackageParser.Package pkg : packages) {
21276             ipw.println("[" + pkg.packageName + "]");
21277             ipw.increaseIndent();
21278             mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
21279             ipw.decreaseIndent();
21280         }
21281     }
21282
21283     private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21284         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21285         ipw.println();
21286         ipw.println("Compiler stats:");
21287         ipw.increaseIndent();
21288         Collection<PackageParser.Package> packages = null;
21289         if (packageName != null) {
21290             PackageParser.Package targetPackage = mPackages.get(packageName);
21291             if (targetPackage != null) {
21292                 packages = Collections.singletonList(targetPackage);
21293             } else {
21294                 ipw.println("Unable to find package: " + packageName);
21295                 return;
21296             }
21297         } else {
21298             packages = mPackages.values();
21299         }
21300
21301         for (PackageParser.Package pkg : packages) {
21302             ipw.println("[" + pkg.packageName + "]");
21303             ipw.increaseIndent();
21304
21305             CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21306             if (stats == null) {
21307                 ipw.println("(No recorded stats)");
21308             } else {
21309                 stats.dump(ipw);
21310             }
21311             ipw.decreaseIndent();
21312         }
21313     }
21314
21315     private void dumpEnabledOverlaysLPr(PrintWriter pw) {
21316         pw.println("Enabled overlay paths:");
21317         final int N = mEnabledOverlayPaths.size();
21318         for (int i = 0; i < N; i++) {
21319             final int userId = mEnabledOverlayPaths.keyAt(i);
21320             pw.println(String.format("    User %d:", userId));
21321             final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
21322                 mEnabledOverlayPaths.valueAt(i);
21323             final int M = userSpecificOverlays.size();
21324             for (int j = 0; j < M; j++) {
21325                 final String targetPackageName = userSpecificOverlays.keyAt(j);
21326                 final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
21327                 pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
21328             }
21329         }
21330     }
21331
21332     private String dumpDomainString(String packageName) {
21333         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21334                 .getList();
21335         List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21336
21337         ArraySet<String> result = new ArraySet<>();
21338         if (iviList.size() > 0) {
21339             for (IntentFilterVerificationInfo ivi : iviList) {
21340                 for (String host : ivi.getDomains()) {
21341                     result.add(host);
21342                 }
21343             }
21344         }
21345         if (filters != null && filters.size() > 0) {
21346             for (IntentFilter filter : filters) {
21347                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21348                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21349                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21350                     result.addAll(filter.getHostsList());
21351                 }
21352             }
21353         }
21354
21355         StringBuilder sb = new StringBuilder(result.size() * 16);
21356         for (String domain : result) {
21357             if (sb.length() > 0) sb.append(" ");
21358             sb.append(domain);
21359         }
21360         return sb.toString();
21361     }
21362
21363     // ------- apps on sdcard specific code -------
21364     static final boolean DEBUG_SD_INSTALL = false;
21365
21366     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21367
21368     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21369
21370     private boolean mMediaMounted = false;
21371
21372     static String getEncryptKey() {
21373         try {
21374             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21375                     SD_ENCRYPTION_KEYSTORE_NAME);
21376             if (sdEncKey == null) {
21377                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21378                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21379                 if (sdEncKey == null) {
21380                     Slog.e(TAG, "Failed to create encryption keys");
21381                     return null;
21382                 }
21383             }
21384             return sdEncKey;
21385         } catch (NoSuchAlgorithmException nsae) {
21386             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21387             return null;
21388         } catch (IOException ioe) {
21389             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21390             return null;
21391         }
21392     }
21393
21394     /*
21395      * Update media status on PackageManager.
21396      */
21397     @Override
21398     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21399         int callingUid = Binder.getCallingUid();
21400         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
21401             throw new SecurityException("Media status can only be updated by the system");
21402         }
21403         // reader; this apparently protects mMediaMounted, but should probably
21404         // be a different lock in that case.
21405         synchronized (mPackages) {
21406             Log.i(TAG, "Updating external media status from "
21407                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
21408                     + (mediaStatus ? "mounted" : "unmounted"));
21409             if (DEBUG_SD_INSTALL)
21410                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21411                         + ", mMediaMounted=" + mMediaMounted);
21412             if (mediaStatus == mMediaMounted) {
21413                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
21414                         : 0, -1);
21415                 mHandler.sendMessage(msg);
21416                 return;
21417             }
21418             mMediaMounted = mediaStatus;
21419         }
21420         // Queue up an async operation since the package installation may take a
21421         // little while.
21422         mHandler.post(new Runnable() {
21423             public void run() {
21424                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
21425             }
21426         });
21427     }
21428
21429     /**
21430      * Called by StorageManagerService when the initial ASECs to scan are available.
21431      * Should block until all the ASEC containers are finished being scanned.
21432      */
21433     public void scanAvailableAsecs() {
21434         updateExternalMediaStatusInner(true, false, false);
21435     }
21436
21437     /*
21438      * Collect information of applications on external media, map them against
21439      * existing containers and update information based on current mount status.
21440      * Please note that we always have to report status if reportStatus has been
21441      * set to true especially when unloading packages.
21442      */
21443     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
21444             boolean externalStorage) {
21445         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
21446         int[] uidArr = EmptyArray.INT;
21447
21448         final String[] list = PackageHelper.getSecureContainerList();
21449         if (ArrayUtils.isEmpty(list)) {
21450             Log.i(TAG, "No secure containers found");
21451         } else {
21452             // Process list of secure containers and categorize them
21453             // as active or stale based on their package internal state.
21454
21455             // reader
21456             synchronized (mPackages) {
21457                 for (String cid : list) {
21458                     // Leave stages untouched for now; installer service owns them
21459                     if (PackageInstallerService.isStageName(cid)) continue;
21460
21461                     if (DEBUG_SD_INSTALL)
21462                         Log.i(TAG, "Processing container " + cid);
21463                     String pkgName = getAsecPackageName(cid);
21464                     if (pkgName == null) {
21465                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
21466                         continue;
21467                     }
21468                     if (DEBUG_SD_INSTALL)
21469                         Log.i(TAG, "Looking for pkg : " + pkgName);
21470
21471                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
21472                     if (ps == null) {
21473                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
21474                         continue;
21475                     }
21476
21477                     /*
21478                      * Skip packages that are not external if we're unmounting
21479                      * external storage.
21480                      */
21481                     if (externalStorage && !isMounted && !isExternal(ps)) {
21482                         continue;
21483                     }
21484
21485                     final AsecInstallArgs args = new AsecInstallArgs(cid,
21486                             getAppDexInstructionSets(ps), ps.isForwardLocked());
21487                     // The package status is changed only if the code path
21488                     // matches between settings and the container id.
21489                     if (ps.codePathString != null
21490                             && ps.codePathString.startsWith(args.getCodePath())) {
21491                         if (DEBUG_SD_INSTALL) {
21492                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
21493                                     + " at code path: " + ps.codePathString);
21494                         }
21495
21496                         // We do have a valid package installed on sdcard
21497                         processCids.put(args, ps.codePathString);
21498                         final int uid = ps.appId;
21499                         if (uid != -1) {
21500                             uidArr = ArrayUtils.appendInt(uidArr, uid);
21501                         }
21502                     } else {
21503                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
21504                                 + ps.codePathString);
21505                     }
21506                 }
21507             }
21508
21509             Arrays.sort(uidArr);
21510         }
21511
21512         // Process packages with valid entries.
21513         if (isMounted) {
21514             if (DEBUG_SD_INSTALL)
21515                 Log.i(TAG, "Loading packages");
21516             loadMediaPackages(processCids, uidArr, externalStorage);
21517             startCleaningPackages();
21518             mInstallerService.onSecureContainersAvailable();
21519         } else {
21520             if (DEBUG_SD_INSTALL)
21521                 Log.i(TAG, "Unloading packages");
21522             unloadMediaPackages(processCids, uidArr, reportStatus);
21523         }
21524     }
21525
21526     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21527             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21528         final int size = infos.size();
21529         final String[] packageNames = new String[size];
21530         final int[] packageUids = new int[size];
21531         for (int i = 0; i < size; i++) {
21532             final ApplicationInfo info = infos.get(i);
21533             packageNames[i] = info.packageName;
21534             packageUids[i] = info.uid;
21535         }
21536         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21537                 finishedReceiver);
21538     }
21539
21540     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21541             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21542         sendResourcesChangedBroadcast(mediaStatus, replacing,
21543                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21544     }
21545
21546     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21547             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21548         int size = pkgList.length;
21549         if (size > 0) {
21550             // Send broadcasts here
21551             Bundle extras = new Bundle();
21552             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21553             if (uidArr != null) {
21554                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21555             }
21556             if (replacing) {
21557                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21558             }
21559             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21560                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21561             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
21562         }
21563     }
21564
21565    /*
21566      * Look at potentially valid container ids from processCids If package
21567      * information doesn't match the one on record or package scanning fails,
21568      * the cid is added to list of removeCids. We currently don't delete stale
21569      * containers.
21570      */
21571     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
21572             boolean externalStorage) {
21573         ArrayList<String> pkgList = new ArrayList<String>();
21574         Set<AsecInstallArgs> keys = processCids.keySet();
21575
21576         for (AsecInstallArgs args : keys) {
21577             String codePath = processCids.get(args);
21578             if (DEBUG_SD_INSTALL)
21579                 Log.i(TAG, "Loading container : " + args.cid);
21580             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
21581             try {
21582                 // Make sure there are no container errors first.
21583                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
21584                     Slog.e(TAG, "Failed to mount cid : " + args.cid
21585                             + " when installing from sdcard");
21586                     continue;
21587                 }
21588                 // Check code path here.
21589                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
21590                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
21591                             + " does not match one in settings " + codePath);
21592                     continue;
21593                 }
21594                 // Parse package
21595                 int parseFlags = mDefParseFlags;
21596                 if (args.isExternalAsec()) {
21597                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
21598                 }
21599                 if (args.isFwdLocked()) {
21600                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
21601                 }
21602
21603                 synchronized (mInstallLock) {
21604                     PackageParser.Package pkg = null;
21605                     try {
21606                         // Sadly we don't know the package name yet to freeze it
21607                         pkg = scanPackageTracedLI(new File(codePath), parseFlags,
21608                                 SCAN_IGNORE_FROZEN, 0, null);
21609                     } catch (PackageManagerException e) {
21610                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
21611                     }
21612                     // Scan the package
21613                     if (pkg != null) {
21614                         /*
21615                          * TODO why is the lock being held? doPostInstall is
21616                          * called in other places without the lock. This needs
21617                          * to be straightened out.
21618                          */
21619                         // writer
21620                         synchronized (mPackages) {
21621                             retCode = PackageManager.INSTALL_SUCCEEDED;
21622                             pkgList.add(pkg.packageName);
21623                             // Post process args
21624                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
21625                                     pkg.applicationInfo.uid);
21626                         }
21627                     } else {
21628                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
21629                     }
21630                 }
21631
21632             } finally {
21633                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
21634                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
21635                 }
21636             }
21637         }
21638         // writer
21639         synchronized (mPackages) {
21640             // If the platform SDK has changed since the last time we booted,
21641             // we need to re-grant app permission to catch any new ones that
21642             // appear. This is really a hack, and means that apps can in some
21643             // cases get permissions that the user didn't initially explicitly
21644             // allow... it would be nice to have some better way to handle
21645             // this situation.
21646             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
21647                     : mSettings.getInternalVersion();
21648             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
21649                     : StorageManager.UUID_PRIVATE_INTERNAL;
21650
21651             int updateFlags = UPDATE_PERMISSIONS_ALL;
21652             if (ver.sdkVersion != mSdkVersion) {
21653                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21654                         + mSdkVersion + "; regranting permissions for external");
21655                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21656             }
21657             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21658
21659             // Yay, everything is now upgraded
21660             ver.forceCurrent();
21661
21662             // can downgrade to reader
21663             // Persist settings
21664             mSettings.writeLPr();
21665         }
21666         // Send a broadcast to let everyone know we are done processing
21667         if (pkgList.size() > 0) {
21668             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
21669         }
21670     }
21671
21672    /*
21673      * Utility method to unload a list of specified containers
21674      */
21675     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
21676         // Just unmount all valid containers.
21677         for (AsecInstallArgs arg : cidArgs) {
21678             synchronized (mInstallLock) {
21679                 arg.doPostDeleteLI(false);
21680            }
21681        }
21682    }
21683
21684     /*
21685      * Unload packages mounted on external media. This involves deleting package
21686      * data from internal structures, sending broadcasts about disabled packages,
21687      * gc'ing to free up references, unmounting all secure containers
21688      * corresponding to packages on external media, and posting a
21689      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
21690      * that we always have to post this message if status has been requested no
21691      * matter what.
21692      */
21693     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
21694             final boolean reportStatus) {
21695         if (DEBUG_SD_INSTALL)
21696             Log.i(TAG, "unloading media packages");
21697         ArrayList<String> pkgList = new ArrayList<String>();
21698         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
21699         final Set<AsecInstallArgs> keys = processCids.keySet();
21700         for (AsecInstallArgs args : keys) {
21701             String pkgName = args.getPackageName();
21702             if (DEBUG_SD_INSTALL)
21703                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
21704             // Delete package internally
21705             PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21706             synchronized (mInstallLock) {
21707                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21708                 final boolean res;
21709                 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
21710                         "unloadMediaPackages")) {
21711                     res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
21712                             null);
21713                 }
21714                 if (res) {
21715                     pkgList.add(pkgName);
21716                 } else {
21717                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
21718                     failedList.add(args);
21719                 }
21720             }
21721         }
21722
21723         // reader
21724         synchronized (mPackages) {
21725             // We didn't update the settings after removing each package;
21726             // write them now for all packages.
21727             mSettings.writeLPr();
21728         }
21729
21730         // We have to absolutely send UPDATED_MEDIA_STATUS only
21731         // after confirming that all the receivers processed the ordered
21732         // broadcast when packages get disabled, force a gc to clean things up.
21733         // and unload all the containers.
21734         if (pkgList.size() > 0) {
21735             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
21736                     new IIntentReceiver.Stub() {
21737                 public void performReceive(Intent intent, int resultCode, String data,
21738                         Bundle extras, boolean ordered, boolean sticky,
21739                         int sendingUser) throws RemoteException {
21740                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
21741                             reportStatus ? 1 : 0, 1, keys);
21742                     mHandler.sendMessage(msg);
21743                 }
21744             });
21745         } else {
21746             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
21747                     keys);
21748             mHandler.sendMessage(msg);
21749         }
21750     }
21751
21752     private void loadPrivatePackages(final VolumeInfo vol) {
21753         mHandler.post(new Runnable() {
21754             @Override
21755             public void run() {
21756                 loadPrivatePackagesInner(vol);
21757             }
21758         });
21759     }
21760
21761     private void loadPrivatePackagesInner(VolumeInfo vol) {
21762         final String volumeUuid = vol.fsUuid;
21763         if (TextUtils.isEmpty(volumeUuid)) {
21764             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21765             return;
21766         }
21767
21768         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21769         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21770         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21771
21772         final VersionInfo ver;
21773         final List<PackageSetting> packages;
21774         synchronized (mPackages) {
21775             ver = mSettings.findOrCreateVersion(volumeUuid);
21776             packages = mSettings.getVolumePackagesLPr(volumeUuid);
21777         }
21778
21779         for (PackageSetting ps : packages) {
21780             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21781             synchronized (mInstallLock) {
21782                 final PackageParser.Package pkg;
21783                 try {
21784                     pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21785                     loaded.add(pkg.applicationInfo);
21786
21787                 } catch (PackageManagerException e) {
21788                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21789                 }
21790
21791                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21792                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21793                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21794                                     | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21795                 }
21796             }
21797         }
21798
21799         // Reconcile app data for all started/unlocked users
21800         final StorageManager sm = mContext.getSystemService(StorageManager.class);
21801         final UserManager um = mContext.getSystemService(UserManager.class);
21802         UserManagerInternal umInternal = getUserManagerInternal();
21803         for (UserInfo user : um.getUsers()) {
21804             final int flags;
21805             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21806                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21807             } else if (umInternal.isUserRunning(user.id)) {
21808                 flags = StorageManager.FLAG_STORAGE_DE;
21809             } else {
21810                 continue;
21811             }
21812
21813             try {
21814                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21815                 synchronized (mInstallLock) {
21816                     reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21817                 }
21818             } catch (IllegalStateException e) {
21819                 // Device was probably ejected, and we'll process that event momentarily
21820                 Slog.w(TAG, "Failed to prepare storage: " + e);
21821             }
21822         }
21823
21824         synchronized (mPackages) {
21825             int updateFlags = UPDATE_PERMISSIONS_ALL;
21826             if (ver.sdkVersion != mSdkVersion) {
21827                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21828                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
21829                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21830             }
21831             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21832
21833             // Yay, everything is now upgraded
21834             ver.forceCurrent();
21835
21836             mSettings.writeLPr();
21837         }
21838
21839         for (PackageFreezer freezer : freezers) {
21840             freezer.close();
21841         }
21842
21843         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21844         sendResourcesChangedBroadcast(true, false, loaded, null);
21845     }
21846
21847     private void unloadPrivatePackages(final VolumeInfo vol) {
21848         mHandler.post(new Runnable() {
21849             @Override
21850             public void run() {
21851                 unloadPrivatePackagesInner(vol);
21852             }
21853         });
21854     }
21855
21856     private void unloadPrivatePackagesInner(VolumeInfo vol) {
21857         final String volumeUuid = vol.fsUuid;
21858         if (TextUtils.isEmpty(volumeUuid)) {
21859             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21860             return;
21861         }
21862
21863         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21864         synchronized (mInstallLock) {
21865         synchronized (mPackages) {
21866             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21867             for (PackageSetting ps : packages) {
21868                 if (ps.pkg == null) continue;
21869
21870                 final ApplicationInfo info = ps.pkg.applicationInfo;
21871                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21872                 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21873
21874                 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21875                         "unloadPrivatePackagesInner")) {
21876                     if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21877                             false, null)) {
21878                         unloaded.add(info);
21879                     } else {
21880                         Slog.w(TAG, "Failed to unload " + ps.codePath);
21881                     }
21882                 }
21883
21884                 // Try very hard to release any references to this package
21885                 // so we don't risk the system server being killed due to
21886                 // open FDs
21887                 AttributeCache.instance().removePackage(ps.name);
21888             }
21889
21890             mSettings.writeLPr();
21891         }
21892         }
21893
21894         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21895         sendResourcesChangedBroadcast(false, false, unloaded, null);
21896
21897         // Try very hard to release any references to this path so we don't risk
21898         // the system server being killed due to open FDs
21899         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21900
21901         for (int i = 0; i < 3; i++) {
21902             System.gc();
21903             System.runFinalization();
21904         }
21905     }
21906
21907     private void assertPackageKnown(String volumeUuid, String packageName)
21908             throws PackageManagerException {
21909         synchronized (mPackages) {
21910             // Normalize package name to handle renamed packages
21911             packageName = normalizePackageNameLPr(packageName);
21912
21913             final PackageSetting ps = mSettings.mPackages.get(packageName);
21914             if (ps == null) {
21915                 throw new PackageManagerException("Package " + packageName + " is unknown");
21916             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21917                 throw new PackageManagerException(
21918                         "Package " + packageName + " found on unknown volume " + volumeUuid
21919                                 + "; expected volume " + ps.volumeUuid);
21920             }
21921         }
21922     }
21923
21924     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21925             throws PackageManagerException {
21926         synchronized (mPackages) {
21927             // Normalize package name to handle renamed packages
21928             packageName = normalizePackageNameLPr(packageName);
21929
21930             final PackageSetting ps = mSettings.mPackages.get(packageName);
21931             if (ps == null) {
21932                 throw new PackageManagerException("Package " + packageName + " is unknown");
21933             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21934                 throw new PackageManagerException(
21935                         "Package " + packageName + " found on unknown volume " + volumeUuid
21936                                 + "; expected volume " + ps.volumeUuid);
21937             } else if (!ps.getInstalled(userId)) {
21938                 throw new PackageManagerException(
21939                         "Package " + packageName + " not installed for user " + userId);
21940             }
21941         }
21942     }
21943
21944     private List<String> collectAbsoluteCodePaths() {
21945         synchronized (mPackages) {
21946             List<String> codePaths = new ArrayList<>();
21947             final int packageCount = mSettings.mPackages.size();
21948             for (int i = 0; i < packageCount; i++) {
21949                 final PackageSetting ps = mSettings.mPackages.valueAt(i);
21950                 codePaths.add(ps.codePath.getAbsolutePath());
21951             }
21952             return codePaths;
21953         }
21954     }
21955
21956     /**
21957      * Examine all apps present on given mounted volume, and destroy apps that
21958      * aren't expected, either due to uninstallation or reinstallation on
21959      * another volume.
21960      */
21961     private void reconcileApps(String volumeUuid) {
21962         List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21963         List<File> filesToDelete = null;
21964
21965         final File[] files = FileUtils.listFilesOrEmpty(
21966                 Environment.getDataAppDirectory(volumeUuid));
21967         for (File file : files) {
21968             final boolean isPackage = (isApkFile(file) || file.isDirectory())
21969                     && !PackageInstallerService.isStageName(file.getName());
21970             if (!isPackage) {
21971                 // Ignore entries which are not packages
21972                 continue;
21973             }
21974
21975             String absolutePath = file.getAbsolutePath();
21976
21977             boolean pathValid = false;
21978             final int absoluteCodePathCount = absoluteCodePaths.size();
21979             for (int i = 0; i < absoluteCodePathCount; i++) {
21980                 String absoluteCodePath = absoluteCodePaths.get(i);
21981                 if (absolutePath.startsWith(absoluteCodePath)) {
21982                     pathValid = true;
21983                     break;
21984                 }
21985             }
21986
21987             if (!pathValid) {
21988                 if (filesToDelete == null) {
21989                     filesToDelete = new ArrayList<>();
21990                 }
21991                 filesToDelete.add(file);
21992             }
21993         }
21994
21995         if (filesToDelete != null) {
21996             final int fileToDeleteCount = filesToDelete.size();
21997             for (int i = 0; i < fileToDeleteCount; i++) {
21998                 File fileToDelete = filesToDelete.get(i);
21999                 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22000                 synchronized (mInstallLock) {
22001                     removeCodePathLI(fileToDelete);
22002                 }
22003             }
22004         }
22005     }
22006
22007     /**
22008      * Reconcile all app data for the given user.
22009      * <p>
22010      * Verifies that directories exist and that ownership and labeling is
22011      * correct for all installed apps on all mounted volumes.
22012      */
22013     void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22014         final StorageManager storage = mContext.getSystemService(StorageManager.class);
22015         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22016             final String volumeUuid = vol.getFsUuid();
22017             synchronized (mInstallLock) {
22018                 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22019             }
22020         }
22021     }
22022
22023     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22024             boolean migrateAppData) {
22025         reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22026     }
22027
22028     /**
22029      * Reconcile all app data on given mounted volume.
22030      * <p>
22031      * Destroys app data that isn't expected, either due to uninstallation or
22032      * reinstallation on another volume.
22033      * <p>
22034      * Verifies that directories exist and that ownership and labeling is
22035      * correct for all installed apps.
22036      * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22037      */
22038     private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22039             boolean migrateAppData, boolean onlyCoreApps) {
22040         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22041                 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22042         List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22043
22044         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22045         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22046
22047         // First look for stale data that doesn't belong, and check if things
22048         // have changed since we did our last restorecon
22049         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22050             if (StorageManager.isFileEncryptedNativeOrEmulated()
22051                     && !StorageManager.isUserKeyUnlocked(userId)) {
22052                 throw new RuntimeException(
22053                         "Yikes, someone asked us to reconcile CE storage while " + userId
22054                                 + " was still locked; this would have caused massive data loss!");
22055             }
22056
22057             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22058             for (File file : files) {
22059                 final String packageName = file.getName();
22060                 try {
22061                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22062                 } catch (PackageManagerException e) {
22063                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22064                     try {
22065                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
22066                                 StorageManager.FLAG_STORAGE_CE, 0);
22067                     } catch (InstallerException e2) {
22068                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22069                     }
22070                 }
22071             }
22072         }
22073         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22074             final File[] files = FileUtils.listFilesOrEmpty(deDir);
22075             for (File file : files) {
22076                 final String packageName = file.getName();
22077                 try {
22078                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22079                 } catch (PackageManagerException e) {
22080                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22081                     try {
22082                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
22083                                 StorageManager.FLAG_STORAGE_DE, 0);
22084                     } catch (InstallerException e2) {
22085                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22086                     }
22087                 }
22088             }
22089         }
22090
22091         // Ensure that data directories are ready to roll for all packages
22092         // installed for this volume and user
22093         final List<PackageSetting> packages;
22094         synchronized (mPackages) {
22095             packages = mSettings.getVolumePackagesLPr(volumeUuid);
22096         }
22097         int preparedCount = 0;
22098         for (PackageSetting ps : packages) {
22099             final String packageName = ps.name;
22100             if (ps.pkg == null) {
22101                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
22102                 // TODO: might be due to legacy ASEC apps; we should circle back
22103                 // and reconcile again once they're scanned
22104                 continue;
22105             }
22106             // Skip non-core apps if requested
22107             if (onlyCoreApps && !ps.pkg.coreApp) {
22108                 result.add(packageName);
22109                 continue;
22110             }
22111
22112             if (ps.getInstalled(userId)) {
22113                 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22114                 preparedCount++;
22115             }
22116         }
22117
22118         Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22119         return result;
22120     }
22121
22122     /**
22123      * Prepare app data for the given app just after it was installed or
22124      * upgraded. This method carefully only touches users that it's installed
22125      * for, and it forces a restorecon to handle any seinfo changes.
22126      * <p>
22127      * Verifies that directories exist and that ownership and labeling is
22128      * correct for all installed apps. If there is an ownership mismatch, it
22129      * will try recovering system apps by wiping data; third-party app data is
22130      * left intact.
22131      * <p>
22132      * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22133      */
22134     private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22135         final PackageSetting ps;
22136         synchronized (mPackages) {
22137             ps = mSettings.mPackages.get(pkg.packageName);
22138             mSettings.writeKernelMappingLPr(ps);
22139         }
22140
22141         final UserManager um = mContext.getSystemService(UserManager.class);
22142         UserManagerInternal umInternal = getUserManagerInternal();
22143         for (UserInfo user : um.getUsers()) {
22144             final int flags;
22145             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22146                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22147             } else if (umInternal.isUserRunning(user.id)) {
22148                 flags = StorageManager.FLAG_STORAGE_DE;
22149             } else {
22150                 continue;
22151             }
22152
22153             if (ps.getInstalled(user.id)) {
22154                 // TODO: when user data is locked, mark that we're still dirty
22155                 prepareAppDataLIF(pkg, user.id, flags);
22156             }
22157         }
22158     }
22159
22160     /**
22161      * Prepare app data for the given app.
22162      * <p>
22163      * Verifies that directories exist and that ownership and labeling is
22164      * correct for all installed apps. If there is an ownership mismatch, this
22165      * will try recovering system apps by wiping data; third-party app data is
22166      * left intact.
22167      */
22168     private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22169         if (pkg == null) {
22170             Slog.wtf(TAG, "Package was null!", new Throwable());
22171             return;
22172         }
22173         prepareAppDataLeafLIF(pkg, userId, flags);
22174         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22175         for (int i = 0; i < childCount; i++) {
22176             prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22177         }
22178     }
22179
22180     private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22181             boolean maybeMigrateAppData) {
22182         prepareAppDataLIF(pkg, userId, flags);
22183
22184         if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22185             // We may have just shuffled around app data directories, so
22186             // prepare them one more time
22187             prepareAppDataLIF(pkg, userId, flags);
22188         }
22189     }
22190
22191     private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22192         if (DEBUG_APP_DATA) {
22193             Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22194                     + Integer.toHexString(flags));
22195         }
22196
22197         final String volumeUuid = pkg.volumeUuid;
22198         final String packageName = pkg.packageName;
22199         final ApplicationInfo app = pkg.applicationInfo;
22200         final int appId = UserHandle.getAppId(app.uid);
22201
22202         Preconditions.checkNotNull(app.seInfo);
22203
22204         long ceDataInode = -1;
22205         try {
22206             ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22207                     appId, app.seInfo, app.targetSdkVersion);
22208         } catch (InstallerException e) {
22209             if (app.isSystemApp()) {
22210                 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22211                         + ", but trying to recover: " + e);
22212                 destroyAppDataLeafLIF(pkg, userId, flags);
22213                 try {
22214                     ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22215                             appId, app.seInfo, app.targetSdkVersion);
22216                     logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22217                 } catch (InstallerException e2) {
22218                     logCriticalInfo(Log.DEBUG, "Recovery failed!");
22219                 }
22220             } else {
22221                 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22222             }
22223         }
22224
22225         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22226             // TODO: mark this structure as dirty so we persist it!
22227             synchronized (mPackages) {
22228                 final PackageSetting ps = mSettings.mPackages.get(packageName);
22229                 if (ps != null) {
22230                     ps.setCeDataInode(ceDataInode, userId);
22231                 }
22232             }
22233         }
22234
22235         prepareAppDataContentsLeafLIF(pkg, userId, flags);
22236     }
22237
22238     private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22239         if (pkg == null) {
22240             Slog.wtf(TAG, "Package was null!", new Throwable());
22241             return;
22242         }
22243         prepareAppDataContentsLeafLIF(pkg, userId, flags);
22244         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22245         for (int i = 0; i < childCount; i++) {
22246             prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22247         }
22248     }
22249
22250     private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22251         final String volumeUuid = pkg.volumeUuid;
22252         final String packageName = pkg.packageName;
22253         final ApplicationInfo app = pkg.applicationInfo;
22254
22255         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22256             // Create a native library symlink only if we have native libraries
22257             // and if the native libraries are 32 bit libraries. We do not provide
22258             // this symlink for 64 bit libraries.
22259             if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22260                 final String nativeLibPath = app.nativeLibraryDir;
22261                 try {
22262                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22263                             nativeLibPath, userId);
22264                 } catch (InstallerException e) {
22265                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22266                 }
22267             }
22268         }
22269     }
22270
22271     /**
22272      * For system apps on non-FBE devices, this method migrates any existing
22273      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22274      * requested by the app.
22275      */
22276     private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22277         if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
22278                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22279             final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22280                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22281             try {
22282                 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22283                         storageTarget);
22284             } catch (InstallerException e) {
22285                 logCriticalInfo(Log.WARN,
22286                         "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22287             }
22288             return true;
22289         } else {
22290             return false;
22291         }
22292     }
22293
22294     public PackageFreezer freezePackage(String packageName, String killReason) {
22295         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22296     }
22297
22298     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22299         return new PackageFreezer(packageName, userId, killReason);
22300     }
22301
22302     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22303             String killReason) {
22304         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22305     }
22306
22307     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22308             String killReason) {
22309         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22310             return new PackageFreezer();
22311         } else {
22312             return freezePackage(packageName, userId, killReason);
22313         }
22314     }
22315
22316     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22317             String killReason) {
22318         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22319     }
22320
22321     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22322             String killReason) {
22323         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22324             return new PackageFreezer();
22325         } else {
22326             return freezePackage(packageName, userId, killReason);
22327         }
22328     }
22329
22330     /**
22331      * Class that freezes and kills the given package upon creation, and
22332      * unfreezes it upon closing. This is typically used when doing surgery on
22333      * app code/data to prevent the app from running while you're working.
22334      */
22335     private class PackageFreezer implements AutoCloseable {
22336         private final String mPackageName;
22337         private final PackageFreezer[] mChildren;
22338
22339         private final boolean mWeFroze;
22340
22341         private final AtomicBoolean mClosed = new AtomicBoolean();
22342         private final CloseGuard mCloseGuard = CloseGuard.get();
22343
22344         /**
22345          * Create and return a stub freezer that doesn't actually do anything,
22346          * typically used when someone requested
22347          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22348          * {@link PackageManager#DELETE_DONT_KILL_APP}.
22349          */
22350         public PackageFreezer() {
22351             mPackageName = null;
22352             mChildren = null;
22353             mWeFroze = false;
22354             mCloseGuard.open("close");
22355         }
22356
22357         public PackageFreezer(String packageName, int userId, String killReason) {
22358             synchronized (mPackages) {
22359                 mPackageName = packageName;
22360                 mWeFroze = mFrozenPackages.add(mPackageName);
22361
22362                 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22363                 if (ps != null) {
22364                     killApplication(ps.name, ps.appId, userId, killReason);
22365                 }
22366
22367                 final PackageParser.Package p = mPackages.get(packageName);
22368                 if (p != null && p.childPackages != null) {
22369                     final int N = p.childPackages.size();
22370                     mChildren = new PackageFreezer[N];
22371                     for (int i = 0; i < N; i++) {
22372                         mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22373                                 userId, killReason);
22374                     }
22375                 } else {
22376                     mChildren = null;
22377                 }
22378             }
22379             mCloseGuard.open("close");
22380         }
22381
22382         @Override
22383         protected void finalize() throws Throwable {
22384             try {
22385                 if (mCloseGuard != null) {
22386                     mCloseGuard.warnIfOpen();
22387                 }
22388
22389                 close();
22390             } finally {
22391                 super.finalize();
22392             }
22393         }
22394
22395         @Override
22396         public void close() {
22397             mCloseGuard.close();
22398             if (mClosed.compareAndSet(false, true)) {
22399                 synchronized (mPackages) {
22400                     if (mWeFroze) {
22401                         mFrozenPackages.remove(mPackageName);
22402                     }
22403
22404                     if (mChildren != null) {
22405                         for (PackageFreezer freezer : mChildren) {
22406                             freezer.close();
22407                         }
22408                     }
22409                 }
22410             }
22411         }
22412     }
22413
22414     /**
22415      * Verify that given package is currently frozen.
22416      */
22417     private void checkPackageFrozen(String packageName) {
22418         synchronized (mPackages) {
22419             if (!mFrozenPackages.contains(packageName)) {
22420                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22421             }
22422         }
22423     }
22424
22425     @Override
22426     public int movePackage(final String packageName, final String volumeUuid) {
22427         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22428
22429         final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
22430         final int moveId = mNextMoveId.getAndIncrement();
22431         mHandler.post(new Runnable() {
22432             @Override
22433             public void run() {
22434                 try {
22435                     movePackageInternal(packageName, volumeUuid, moveId, user);
22436                 } catch (PackageManagerException e) {
22437                     Slog.w(TAG, "Failed to move " + packageName, e);
22438                     mMoveCallbacks.notifyStatusChanged(moveId,
22439                             PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22440                 }
22441             }
22442         });
22443         return moveId;
22444     }
22445
22446     private void movePackageInternal(final String packageName, final String volumeUuid,
22447             final int moveId, UserHandle user) throws PackageManagerException {
22448         final StorageManager storage = mContext.getSystemService(StorageManager.class);
22449         final PackageManager pm = mContext.getPackageManager();
22450
22451         final boolean currentAsec;
22452         final String currentVolumeUuid;
22453         final File codeFile;
22454         final String installerPackageName;
22455         final String packageAbiOverride;
22456         final int appId;
22457         final String seinfo;
22458         final String label;
22459         final int targetSdkVersion;
22460         final PackageFreezer freezer;
22461         final int[] installedUserIds;
22462
22463         // reader
22464         synchronized (mPackages) {
22465             final PackageParser.Package pkg = mPackages.get(packageName);
22466             final PackageSetting ps = mSettings.mPackages.get(packageName);
22467             if (pkg == null || ps == null) {
22468                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22469             }
22470
22471             if (pkg.applicationInfo.isSystemApp()) {
22472                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22473                         "Cannot move system application");
22474             }
22475
22476             final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22477             final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22478                     com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22479             if (isInternalStorage && !allow3rdPartyOnInternal) {
22480                 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22481                         "3rd party apps are not allowed on internal storage");
22482             }
22483
22484             if (pkg.applicationInfo.isExternalAsec()) {
22485                 currentAsec = true;
22486                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22487             } else if (pkg.applicationInfo.isForwardLocked()) {
22488                 currentAsec = true;
22489                 currentVolumeUuid = "forward_locked";
22490             } else {
22491                 currentAsec = false;
22492                 currentVolumeUuid = ps.volumeUuid;
22493
22494                 final File probe = new File(pkg.codePath);
22495                 final File probeOat = new File(probe, "oat");
22496                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
22497                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22498                             "Move only supported for modern cluster style installs");
22499                 }
22500             }
22501
22502             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22503                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22504                         "Package already moved to " + volumeUuid);
22505             }
22506             if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22507                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22508                         "Device admin cannot be moved");
22509             }
22510
22511             if (mFrozenPackages.contains(packageName)) {
22512                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22513                         "Failed to move already frozen package");
22514             }
22515
22516             codeFile = new File(pkg.codePath);
22517             installerPackageName = ps.installerPackageName;
22518             packageAbiOverride = ps.cpuAbiOverrideString;
22519             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22520             seinfo = pkg.applicationInfo.seInfo;
22521             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22522             targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22523             freezer = freezePackage(packageName, "movePackageInternal");
22524             installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22525         }
22526
22527         final Bundle extras = new Bundle();
22528         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22529         extras.putString(Intent.EXTRA_TITLE, label);
22530         mMoveCallbacks.notifyCreated(moveId, extras);
22531
22532         int installFlags;
22533         final boolean moveCompleteApp;
22534         final File measurePath;
22535
22536         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22537             installFlags = INSTALL_INTERNAL;
22538             moveCompleteApp = !currentAsec;
22539             measurePath = Environment.getDataAppDirectory(volumeUuid);
22540         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22541             installFlags = INSTALL_EXTERNAL;
22542             moveCompleteApp = false;
22543             measurePath = storage.getPrimaryPhysicalVolume().getPath();
22544         } else {
22545             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22546             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22547                     || !volume.isMountedWritable()) {
22548                 freezer.close();
22549                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22550                         "Move location not mounted private volume");
22551             }
22552
22553             Preconditions.checkState(!currentAsec);
22554
22555             installFlags = INSTALL_INTERNAL;
22556             moveCompleteApp = true;
22557             measurePath = Environment.getDataAppDirectory(volumeUuid);
22558         }
22559
22560         final PackageStats stats = new PackageStats(null, -1);
22561         synchronized (mInstaller) {
22562             for (int userId : installedUserIds) {
22563                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22564                     freezer.close();
22565                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22566                             "Failed to measure package size");
22567                 }
22568             }
22569         }
22570
22571         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22572                 + stats.dataSize);
22573
22574         final long startFreeBytes = measurePath.getUsableSpace();
22575         final long sizeBytes;
22576         if (moveCompleteApp) {
22577             sizeBytes = stats.codeSize + stats.dataSize;
22578         } else {
22579             sizeBytes = stats.codeSize;
22580         }
22581
22582         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22583             freezer.close();
22584             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22585                     "Not enough free space to move");
22586         }
22587
22588         mMoveCallbacks.notifyStatusChanged(moveId, 10);
22589
22590         final CountDownLatch installedLatch = new CountDownLatch(1);
22591         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22592             @Override
22593             public void onUserActionRequired(Intent intent) throws RemoteException {
22594                 throw new IllegalStateException();
22595             }
22596
22597             @Override
22598             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22599                     Bundle extras) throws RemoteException {
22600                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22601                         + PackageManager.installStatusToString(returnCode, msg));
22602
22603                 installedLatch.countDown();
22604                 freezer.close();
22605
22606                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
22607                 switch (status) {
22608                     case PackageInstaller.STATUS_SUCCESS:
22609                         mMoveCallbacks.notifyStatusChanged(moveId,
22610                                 PackageManager.MOVE_SUCCEEDED);
22611                         break;
22612                     case PackageInstaller.STATUS_FAILURE_STORAGE:
22613                         mMoveCallbacks.notifyStatusChanged(moveId,
22614                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22615                         break;
22616                     default:
22617                         mMoveCallbacks.notifyStatusChanged(moveId,
22618                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22619                         break;
22620                 }
22621             }
22622         };
22623
22624         final MoveInfo move;
22625         if (moveCompleteApp) {
22626             // Kick off a thread to report progress estimates
22627             new Thread() {
22628                 @Override
22629                 public void run() {
22630                     while (true) {
22631                         try {
22632                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
22633                                 break;
22634                             }
22635                         } catch (InterruptedException ignored) {
22636                         }
22637
22638                         final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22639                         final int progress = 10 + (int) MathUtils.constrain(
22640                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22641                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
22642                     }
22643                 }
22644             }.start();
22645
22646             final String dataAppName = codeFile.getName();
22647             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22648                     dataAppName, appId, seinfo, targetSdkVersion);
22649         } else {
22650             move = null;
22651         }
22652
22653         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22654
22655         final Message msg = mHandler.obtainMessage(INIT_COPY);
22656         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22657         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22658                 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22659                 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22660                 PackageManager.INSTALL_REASON_UNKNOWN);
22661         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22662         msg.obj = params;
22663
22664         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22665                 System.identityHashCode(msg.obj));
22666         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22667                 System.identityHashCode(msg.obj));
22668
22669         mHandler.sendMessage(msg);
22670     }
22671
22672     @Override
22673     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22674         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22675
22676         final int realMoveId = mNextMoveId.getAndIncrement();
22677         final Bundle extras = new Bundle();
22678         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22679         mMoveCallbacks.notifyCreated(realMoveId, extras);
22680
22681         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22682             @Override
22683             public void onCreated(int moveId, Bundle extras) {
22684                 // Ignored
22685             }
22686
22687             @Override
22688             public void onStatusChanged(int moveId, int status, long estMillis) {
22689                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22690             }
22691         };
22692
22693         final StorageManager storage = mContext.getSystemService(StorageManager.class);
22694         storage.setPrimaryStorageUuid(volumeUuid, callback);
22695         return realMoveId;
22696     }
22697
22698     @Override
22699     public int getMoveStatus(int moveId) {
22700         mContext.enforceCallingOrSelfPermission(
22701                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22702         return mMoveCallbacks.mLastStatus.get(moveId);
22703     }
22704
22705     @Override
22706     public void registerMoveCallback(IPackageMoveObserver callback) {
22707         mContext.enforceCallingOrSelfPermission(
22708                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22709         mMoveCallbacks.register(callback);
22710     }
22711
22712     @Override
22713     public void unregisterMoveCallback(IPackageMoveObserver callback) {
22714         mContext.enforceCallingOrSelfPermission(
22715                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22716         mMoveCallbacks.unregister(callback);
22717     }
22718
22719     @Override
22720     public boolean setInstallLocation(int loc) {
22721         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22722                 null);
22723         if (getInstallLocation() == loc) {
22724             return true;
22725         }
22726         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22727                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22728             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22729                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22730             return true;
22731         }
22732         return false;
22733    }
22734
22735     @Override
22736     public int getInstallLocation() {
22737         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22738                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22739                 PackageHelper.APP_INSTALL_AUTO);
22740     }
22741
22742     /** Called by UserManagerService */
22743     void cleanUpUser(UserManagerService userManager, int userHandle) {
22744         synchronized (mPackages) {
22745             mDirtyUsers.remove(userHandle);
22746             mUserNeedsBadging.delete(userHandle);
22747             mSettings.removeUserLPw(userHandle);
22748             mPendingBroadcasts.remove(userHandle);
22749             mInstantAppRegistry.onUserRemovedLPw(userHandle);
22750             removeUnusedPackagesLPw(userManager, userHandle);
22751         }
22752     }
22753
22754     /**
22755      * We're removing userHandle and would like to remove any downloaded packages
22756      * that are no longer in use by any other user.
22757      * @param userHandle the user being removed
22758      */
22759     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22760         final boolean DEBUG_CLEAN_APKS = false;
22761         int [] users = userManager.getUserIds();
22762         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22763         while (psit.hasNext()) {
22764             PackageSetting ps = psit.next();
22765             if (ps.pkg == null) {
22766                 continue;
22767             }
22768             final String packageName = ps.pkg.packageName;
22769             // Skip over if system app
22770             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22771                 continue;
22772             }
22773             if (DEBUG_CLEAN_APKS) {
22774                 Slog.i(TAG, "Checking package " + packageName);
22775             }
22776             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22777             if (keep) {
22778                 if (DEBUG_CLEAN_APKS) {
22779                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22780                 }
22781             } else {
22782                 for (int i = 0; i < users.length; i++) {
22783                     if (users[i] != userHandle && ps.getInstalled(users[i])) {
22784                         keep = true;
22785                         if (DEBUG_CLEAN_APKS) {
22786                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
22787                                     + users[i]);
22788                         }
22789                         break;
22790                     }
22791                 }
22792             }
22793             if (!keep) {
22794                 if (DEBUG_CLEAN_APKS) {
22795                     Slog.i(TAG, "  Removing package " + packageName);
22796                 }
22797                 mHandler.post(new Runnable() {
22798                     public void run() {
22799                         deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22800                                 userHandle, 0);
22801                     } //end run
22802                 });
22803             }
22804         }
22805     }
22806
22807     /** Called by UserManagerService */
22808     void createNewUser(int userId, String[] disallowedPackages) {
22809         synchronized (mInstallLock) {
22810             mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22811         }
22812         synchronized (mPackages) {
22813             scheduleWritePackageRestrictionsLocked(userId);
22814             scheduleWritePackageListLocked(userId);
22815             applyFactoryDefaultBrowserLPw(userId);
22816             primeDomainVerificationsLPw(userId);
22817         }
22818     }
22819
22820     void onNewUserCreated(final int userId) {
22821         mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22822         // If permission review for legacy apps is required, we represent
22823         // dagerous permissions for such apps as always granted runtime
22824         // permissions to keep per user flag state whether review is needed.
22825         // Hence, if a new user is added we have to propagate dangerous
22826         // permission grants for these legacy apps.
22827         if (mPermissionReviewRequired) {
22828             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
22829                     | UPDATE_PERMISSIONS_REPLACE_ALL);
22830         }
22831     }
22832
22833     @Override
22834     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22835         mContext.enforceCallingOrSelfPermission(
22836                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22837                 "Only package verification agents can read the verifier device identity");
22838
22839         synchronized (mPackages) {
22840             return mSettings.getVerifierDeviceIdentityLPw();
22841         }
22842     }
22843
22844     @Override
22845     public void setPermissionEnforced(String permission, boolean enforced) {
22846         // TODO: Now that we no longer change GID for storage, this should to away.
22847         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22848                 "setPermissionEnforced");
22849         if (READ_EXTERNAL_STORAGE.equals(permission)) {
22850             synchronized (mPackages) {
22851                 if (mSettings.mReadExternalStorageEnforced == null
22852                         || mSettings.mReadExternalStorageEnforced != enforced) {
22853                     mSettings.mReadExternalStorageEnforced = enforced;
22854                     mSettings.writeLPr();
22855                 }
22856             }
22857             // kill any non-foreground processes so we restart them and
22858             // grant/revoke the GID.
22859             final IActivityManager am = ActivityManager.getService();
22860             if (am != null) {
22861                 final long token = Binder.clearCallingIdentity();
22862                 try {
22863                     am.killProcessesBelowForeground("setPermissionEnforcement");
22864                 } catch (RemoteException e) {
22865                 } finally {
22866                     Binder.restoreCallingIdentity(token);
22867                 }
22868             }
22869         } else {
22870             throw new IllegalArgumentException("No selective enforcement for " + permission);
22871         }
22872     }
22873
22874     @Override
22875     @Deprecated
22876     public boolean isPermissionEnforced(String permission) {
22877         return true;
22878     }
22879
22880     @Override
22881     public boolean isStorageLow() {
22882         final long token = Binder.clearCallingIdentity();
22883         try {
22884             final DeviceStorageMonitorInternal
22885                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22886             if (dsm != null) {
22887                 return dsm.isMemoryLow();
22888             } else {
22889                 return false;
22890             }
22891         } finally {
22892             Binder.restoreCallingIdentity(token);
22893         }
22894     }
22895
22896     @Override
22897     public IPackageInstaller getPackageInstaller() {
22898         return mInstallerService;
22899     }
22900
22901     private boolean userNeedsBadging(int userId) {
22902         int index = mUserNeedsBadging.indexOfKey(userId);
22903         if (index < 0) {
22904             final UserInfo userInfo;
22905             final long token = Binder.clearCallingIdentity();
22906             try {
22907                 userInfo = sUserManager.getUserInfo(userId);
22908             } finally {
22909                 Binder.restoreCallingIdentity(token);
22910             }
22911             final boolean b;
22912             if (userInfo != null && userInfo.isManagedProfile()) {
22913                 b = true;
22914             } else {
22915                 b = false;
22916             }
22917             mUserNeedsBadging.put(userId, b);
22918             return b;
22919         }
22920         return mUserNeedsBadging.valueAt(index);
22921     }
22922
22923     @Override
22924     public KeySet getKeySetByAlias(String packageName, String alias) {
22925         if (packageName == null || alias == null) {
22926             return null;
22927         }
22928         synchronized(mPackages) {
22929             final PackageParser.Package pkg = mPackages.get(packageName);
22930             if (pkg == null) {
22931                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22932                 throw new IllegalArgumentException("Unknown package: " + packageName);
22933             }
22934             KeySetManagerService ksms = mSettings.mKeySetManagerService;
22935             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22936         }
22937     }
22938
22939     @Override
22940     public KeySet getSigningKeySet(String packageName) {
22941         if (packageName == null) {
22942             return null;
22943         }
22944         synchronized(mPackages) {
22945             final PackageParser.Package pkg = mPackages.get(packageName);
22946             if (pkg == null) {
22947                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22948                 throw new IllegalArgumentException("Unknown package: " + packageName);
22949             }
22950             if (pkg.applicationInfo.uid != Binder.getCallingUid()
22951                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
22952                 throw new SecurityException("May not access signing KeySet of other apps.");
22953             }
22954             KeySetManagerService ksms = mSettings.mKeySetManagerService;
22955             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22956         }
22957     }
22958
22959     @Override
22960     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22961         if (packageName == null || ks == null) {
22962             return false;
22963         }
22964         synchronized(mPackages) {
22965             final PackageParser.Package pkg = mPackages.get(packageName);
22966             if (pkg == null) {
22967                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22968                 throw new IllegalArgumentException("Unknown package: " + packageName);
22969             }
22970             IBinder ksh = ks.getToken();
22971             if (ksh instanceof KeySetHandle) {
22972                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22973                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22974             }
22975             return false;
22976         }
22977     }
22978
22979     @Override
22980     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22981         if (packageName == null || ks == null) {
22982             return false;
22983         }
22984         synchronized(mPackages) {
22985             final PackageParser.Package pkg = mPackages.get(packageName);
22986             if (pkg == null) {
22987                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22988                 throw new IllegalArgumentException("Unknown package: " + packageName);
22989             }
22990             IBinder ksh = ks.getToken();
22991             if (ksh instanceof KeySetHandle) {
22992                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
22993                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22994             }
22995             return false;
22996         }
22997     }
22998
22999     private void deletePackageIfUnusedLPr(final String packageName) {
23000         PackageSetting ps = mSettings.mPackages.get(packageName);
23001         if (ps == null) {
23002             return;
23003         }
23004         if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23005             // TODO Implement atomic delete if package is unused
23006             // It is currently possible that the package will be deleted even if it is installed
23007             // after this method returns.
23008             mHandler.post(new Runnable() {
23009                 public void run() {
23010                     deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23011                             0, PackageManager.DELETE_ALL_USERS);
23012                 }
23013             });
23014         }
23015     }
23016
23017     /**
23018      * Check and throw if the given before/after packages would be considered a
23019      * downgrade.
23020      */
23021     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23022             throws PackageManagerException {
23023         if (after.versionCode < before.mVersionCode) {
23024             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23025                     "Update version code " + after.versionCode + " is older than current "
23026                     + before.mVersionCode);
23027         } else if (after.versionCode == before.mVersionCode) {
23028             if (after.baseRevisionCode < before.baseRevisionCode) {
23029                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23030                         "Update base revision code " + after.baseRevisionCode
23031                         + " is older than current " + before.baseRevisionCode);
23032             }
23033
23034             if (!ArrayUtils.isEmpty(after.splitNames)) {
23035                 for (int i = 0; i < after.splitNames.length; i++) {
23036                     final String splitName = after.splitNames[i];
23037                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23038                     if (j != -1) {
23039                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23040                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23041                                     "Update split " + splitName + " revision code "
23042                                     + after.splitRevisionCodes[i] + " is older than current "
23043                                     + before.splitRevisionCodes[j]);
23044                         }
23045                     }
23046                 }
23047             }
23048         }
23049     }
23050
23051     private static class MoveCallbacks extends Handler {
23052         private static final int MSG_CREATED = 1;
23053         private static final int MSG_STATUS_CHANGED = 2;
23054
23055         private final RemoteCallbackList<IPackageMoveObserver>
23056                 mCallbacks = new RemoteCallbackList<>();
23057
23058         private final SparseIntArray mLastStatus = new SparseIntArray();
23059
23060         public MoveCallbacks(Looper looper) {
23061             super(looper);
23062         }
23063
23064         public void register(IPackageMoveObserver callback) {
23065             mCallbacks.register(callback);
23066         }
23067
23068         public void unregister(IPackageMoveObserver callback) {
23069             mCallbacks.unregister(callback);
23070         }
23071
23072         @Override
23073         public void handleMessage(Message msg) {
23074             final SomeArgs args = (SomeArgs) msg.obj;
23075             final int n = mCallbacks.beginBroadcast();
23076             for (int i = 0; i < n; i++) {
23077                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23078                 try {
23079                     invokeCallback(callback, msg.what, args);
23080                 } catch (RemoteException ignored) {
23081                 }
23082             }
23083             mCallbacks.finishBroadcast();
23084             args.recycle();
23085         }
23086
23087         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23088                 throws RemoteException {
23089             switch (what) {
23090                 case MSG_CREATED: {
23091                     callback.onCreated(args.argi1, (Bundle) args.arg2);
23092                     break;
23093                 }
23094                 case MSG_STATUS_CHANGED: {
23095                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23096                     break;
23097                 }
23098             }
23099         }
23100
23101         private void notifyCreated(int moveId, Bundle extras) {
23102             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23103
23104             final SomeArgs args = SomeArgs.obtain();
23105             args.argi1 = moveId;
23106             args.arg2 = extras;
23107             obtainMessage(MSG_CREATED, args).sendToTarget();
23108         }
23109
23110         private void notifyStatusChanged(int moveId, int status) {
23111             notifyStatusChanged(moveId, status, -1);
23112         }
23113
23114         private void notifyStatusChanged(int moveId, int status, long estMillis) {
23115             Slog.v(TAG, "Move " + moveId + " status " + status);
23116
23117             final SomeArgs args = SomeArgs.obtain();
23118             args.argi1 = moveId;
23119             args.argi2 = status;
23120             args.arg3 = estMillis;
23121             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23122
23123             synchronized (mLastStatus) {
23124                 mLastStatus.put(moveId, status);
23125             }
23126         }
23127     }
23128
23129     private final static class OnPermissionChangeListeners extends Handler {
23130         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23131
23132         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23133                 new RemoteCallbackList<>();
23134
23135         public OnPermissionChangeListeners(Looper looper) {
23136             super(looper);
23137         }
23138
23139         @Override
23140         public void handleMessage(Message msg) {
23141             switch (msg.what) {
23142                 case MSG_ON_PERMISSIONS_CHANGED: {
23143                     final int uid = msg.arg1;
23144                     handleOnPermissionsChanged(uid);
23145                 } break;
23146             }
23147         }
23148
23149         public void addListenerLocked(IOnPermissionsChangeListener listener) {
23150             mPermissionListeners.register(listener);
23151
23152         }
23153
23154         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23155             mPermissionListeners.unregister(listener);
23156         }
23157
23158         public void onPermissionsChanged(int uid) {
23159             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23160                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23161             }
23162         }
23163
23164         private void handleOnPermissionsChanged(int uid) {
23165             final int count = mPermissionListeners.beginBroadcast();
23166             try {
23167                 for (int i = 0; i < count; i++) {
23168                     IOnPermissionsChangeListener callback = mPermissionListeners
23169                             .getBroadcastItem(i);
23170                     try {
23171                         callback.onPermissionsChanged(uid);
23172                     } catch (RemoteException e) {
23173                         Log.e(TAG, "Permission listener is dead", e);
23174                     }
23175                 }
23176             } finally {
23177                 mPermissionListeners.finishBroadcast();
23178             }
23179         }
23180     }
23181
23182     private class PackageManagerInternalImpl extends PackageManagerInternal {
23183         @Override
23184         public void setLocationPackagesProvider(PackagesProvider provider) {
23185             synchronized (mPackages) {
23186                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
23187             }
23188         }
23189
23190         @Override
23191         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23192             synchronized (mPackages) {
23193                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
23194             }
23195         }
23196
23197         @Override
23198         public void setSmsAppPackagesProvider(PackagesProvider provider) {
23199             synchronized (mPackages) {
23200                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
23201             }
23202         }
23203
23204         @Override
23205         public void setDialerAppPackagesProvider(PackagesProvider provider) {
23206             synchronized (mPackages) {
23207                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
23208             }
23209         }
23210
23211         @Override
23212         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23213             synchronized (mPackages) {
23214                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
23215             }
23216         }
23217
23218         @Override
23219         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23220             synchronized (mPackages) {
23221                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
23222             }
23223         }
23224
23225         @Override
23226         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23227             synchronized (mPackages) {
23228                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
23229                         packageName, userId);
23230             }
23231         }
23232
23233         @Override
23234         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23235             synchronized (mPackages) {
23236                 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23237                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
23238                         packageName, userId);
23239             }
23240         }
23241
23242         @Override
23243         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23244             synchronized (mPackages) {
23245                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
23246                         packageName, userId);
23247             }
23248         }
23249
23250         @Override
23251         public void setKeepUninstalledPackages(final List<String> packageList) {
23252             Preconditions.checkNotNull(packageList);
23253             List<String> removedFromList = null;
23254             synchronized (mPackages) {
23255                 if (mKeepUninstalledPackages != null) {
23256                     final int packagesCount = mKeepUninstalledPackages.size();
23257                     for (int i = 0; i < packagesCount; i++) {
23258                         String oldPackage = mKeepUninstalledPackages.get(i);
23259                         if (packageList != null && packageList.contains(oldPackage)) {
23260                             continue;
23261                         }
23262                         if (removedFromList == null) {
23263                             removedFromList = new ArrayList<>();
23264                         }
23265                         removedFromList.add(oldPackage);
23266                     }
23267                 }
23268                 mKeepUninstalledPackages = new ArrayList<>(packageList);
23269                 if (removedFromList != null) {
23270                     final int removedCount = removedFromList.size();
23271                     for (int i = 0; i < removedCount; i++) {
23272                         deletePackageIfUnusedLPr(removedFromList.get(i));
23273                     }
23274                 }
23275             }
23276         }
23277
23278         @Override
23279         public boolean isPermissionsReviewRequired(String packageName, int userId) {
23280             synchronized (mPackages) {
23281                 // If we do not support permission review, done.
23282                 if (!mPermissionReviewRequired) {
23283                     return false;
23284                 }
23285
23286                 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23287                 if (packageSetting == null) {
23288                     return false;
23289                 }
23290
23291                 // Permission review applies only to apps not supporting the new permission model.
23292                 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
23293                     return false;
23294                 }
23295
23296                 // Legacy apps have the permission and get user consent on launch.
23297                 PermissionsState permissionsState = packageSetting.getPermissionsState();
23298                 return permissionsState.isPermissionReviewRequired(userId);
23299             }
23300         }
23301
23302         @Override
23303         public ApplicationInfo getApplicationInfo(String packageName, int userId) {
23304             return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
23305         }
23306
23307         @Override
23308         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23309                 int userId) {
23310             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23311         }
23312
23313         @Override
23314         public void setDeviceAndProfileOwnerPackages(
23315                 int deviceOwnerUserId, String deviceOwnerPackage,
23316                 SparseArray<String> profileOwnerPackages) {
23317             mProtectedPackages.setDeviceAndProfileOwnerPackages(
23318                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23319         }
23320
23321         @Override
23322         public boolean isPackageDataProtected(int userId, String packageName) {
23323             return mProtectedPackages.isPackageDataProtected(userId, packageName);
23324         }
23325
23326         @Override
23327         public boolean isPackageEphemeral(int userId, String packageName) {
23328             synchronized (mPackages) {
23329                 final PackageSetting ps = mSettings.mPackages.get(packageName);
23330                 return ps != null ? ps.getInstantApp(userId) : false;
23331             }
23332         }
23333
23334         @Override
23335         public boolean wasPackageEverLaunched(String packageName, int userId) {
23336             synchronized (mPackages) {
23337                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23338             }
23339         }
23340
23341         @Override
23342         public void grantRuntimePermission(String packageName, String name, int userId,
23343                 boolean overridePolicy) {
23344             PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23345                     overridePolicy);
23346         }
23347
23348         @Override
23349         public void revokeRuntimePermission(String packageName, String name, int userId,
23350                 boolean overridePolicy) {
23351             PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23352                     overridePolicy);
23353         }
23354
23355         @Override
23356         public String getNameForUid(int uid) {
23357             return PackageManagerService.this.getNameForUid(uid);
23358         }
23359
23360         @Override
23361         public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23362                 Intent origIntent, String resolvedType, String callingPackage, int userId) {
23363             PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23364                     responseObj, origIntent, resolvedType, callingPackage, userId);
23365         }
23366
23367         @Override
23368         public void grantEphemeralAccess(int userId, Intent intent,
23369                 int targetAppId, int ephemeralAppId) {
23370             synchronized (mPackages) {
23371                 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23372                         targetAppId, ephemeralAppId);
23373             }
23374         }
23375
23376         @Override
23377         public boolean isInstantAppInstallerComponent(ComponentName component) {
23378             synchronized (mPackages) {
23379                 return mInstantAppInstallerActivity != null
23380                         && mInstantAppInstallerActivity.getComponentName().equals(component);
23381             }
23382         }
23383
23384         @Override
23385         public void pruneInstantApps() {
23386             synchronized (mPackages) {
23387                 mInstantAppRegistry.pruneInstantAppsLPw();
23388             }
23389         }
23390
23391         @Override
23392         public String getSetupWizardPackageName() {
23393             return mSetupWizardPackage;
23394         }
23395
23396         public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23397             if (policy != null) {
23398                 mExternalSourcesPolicy = policy;
23399             }
23400         }
23401
23402         @Override
23403         public boolean isPackagePersistent(String packageName) {
23404             synchronized (mPackages) {
23405                 PackageParser.Package pkg = mPackages.get(packageName);
23406                 return pkg != null
23407                         ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23408                                         | ApplicationInfo.FLAG_PERSISTENT)) ==
23409                                 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23410                         : false;
23411             }
23412         }
23413
23414         @Override
23415         public List<PackageInfo> getOverlayPackages(int userId) {
23416             final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23417             synchronized (mPackages) {
23418                 for (PackageParser.Package p : mPackages.values()) {
23419                     if (p.mOverlayTarget != null) {
23420                         PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23421                         if (pkg != null) {
23422                             overlayPackages.add(pkg);
23423                         }
23424                     }
23425                 }
23426             }
23427             return overlayPackages;
23428         }
23429
23430         @Override
23431         public List<String> getTargetPackageNames(int userId) {
23432             List<String> targetPackages = new ArrayList<>();
23433             synchronized (mPackages) {
23434                 for (PackageParser.Package p : mPackages.values()) {
23435                     if (p.mOverlayTarget == null) {
23436                         targetPackages.add(p.packageName);
23437                     }
23438                 }
23439             }
23440             return targetPackages;
23441         }
23442
23443         @Override
23444         public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23445                 @Nullable List<String> overlayPackageNames) {
23446             synchronized (mPackages) {
23447                 if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23448                     Slog.e(TAG, "failed to find package " + targetPackageName);
23449                     return false;
23450                 }
23451
23452                 ArrayList<String> paths = null;
23453                 if (overlayPackageNames != null) {
23454                     final int N = overlayPackageNames.size();
23455                     paths = new ArrayList<>(N);
23456                     for (int i = 0; i < N; i++) {
23457                         final String packageName = overlayPackageNames.get(i);
23458                         final PackageParser.Package pkg = mPackages.get(packageName);
23459                         if (pkg == null) {
23460                             Slog.e(TAG, "failed to find package " + packageName);
23461                             return false;
23462                         }
23463                         paths.add(pkg.baseCodePath);
23464                     }
23465                 }
23466
23467                 ArrayMap<String, ArrayList<String>> userSpecificOverlays =
23468                     mEnabledOverlayPaths.get(userId);
23469                 if (userSpecificOverlays == null) {
23470                     userSpecificOverlays = new ArrayMap<>();
23471                     mEnabledOverlayPaths.put(userId, userSpecificOverlays);
23472                 }
23473
23474                 if (paths != null && paths.size() > 0) {
23475                     userSpecificOverlays.put(targetPackageName, paths);
23476                 } else {
23477                     userSpecificOverlays.remove(targetPackageName);
23478                 }
23479                 return true;
23480             }
23481         }
23482
23483         @Override
23484         public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23485                 int flags, int userId) {
23486             return resolveIntentInternal(
23487                     intent, resolvedType, flags, userId, true /*includeInstantApps*/);
23488         }
23489
23490         @Override
23491         public ResolveInfo resolveService(Intent intent, String resolvedType,
23492                 int flags, int userId, int callingUid) {
23493             return resolveServiceInternal(
23494                     intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
23495         }
23496
23497         @Override
23498         public void addIsolatedUid(int isolatedUid, int ownerUid) {
23499             synchronized (mPackages) {
23500                 mIsolatedOwners.put(isolatedUid, ownerUid);
23501             }
23502         }
23503
23504         @Override
23505         public void removeIsolatedUid(int isolatedUid) {
23506             synchronized (mPackages) {
23507                 mIsolatedOwners.delete(isolatedUid);
23508             }
23509         }
23510     }
23511
23512     @Override
23513     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23514         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23515         synchronized (mPackages) {
23516             final long identity = Binder.clearCallingIdentity();
23517             try {
23518                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
23519                         packageNames, userId);
23520             } finally {
23521                 Binder.restoreCallingIdentity(identity);
23522             }
23523         }
23524     }
23525
23526     @Override
23527     public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23528         enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23529         synchronized (mPackages) {
23530             final long identity = Binder.clearCallingIdentity();
23531             try {
23532                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
23533                         packageNames, userId);
23534             } finally {
23535                 Binder.restoreCallingIdentity(identity);
23536             }
23537         }
23538     }
23539
23540     private static void enforceSystemOrPhoneCaller(String tag) {
23541         int callingUid = Binder.getCallingUid();
23542         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23543             throw new SecurityException(
23544                     "Cannot call " + tag + " from UID " + callingUid);
23545         }
23546     }
23547
23548     boolean isHistoricalPackageUsageAvailable() {
23549         return mPackageUsage.isHistoricalPackageUsageAvailable();
23550     }
23551
23552     /**
23553      * Return a <b>copy</b> of the collection of packages known to the package manager.
23554      * @return A copy of the values of mPackages.
23555      */
23556     Collection<PackageParser.Package> getPackages() {
23557         synchronized (mPackages) {
23558             return new ArrayList<>(mPackages.values());
23559         }
23560     }
23561
23562     /**
23563      * Logs process start information (including base APK hash) to the security log.
23564      * @hide
23565      */
23566     public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23567             String apkFile, int pid) {
23568         if (!SecurityLog.isLoggingEnabled()) {
23569             return;
23570         }
23571         Bundle data = new Bundle();
23572         data.putLong("startTimestamp", System.currentTimeMillis());
23573         data.putString("processName", processName);
23574         data.putInt("uid", uid);
23575         data.putString("seinfo", seinfo);
23576         data.putString("apkFile", apkFile);
23577         data.putInt("pid", pid);
23578         Message msg = mProcessLoggingHandler.obtainMessage(
23579                 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23580         msg.setData(data);
23581         mProcessLoggingHandler.sendMessage(msg);
23582     }
23583
23584     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23585         return mCompilerStats.getPackageStats(pkgName);
23586     }
23587
23588     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23589         return getOrCreateCompilerPackageStats(pkg.packageName);
23590     }
23591
23592     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23593         return mCompilerStats.getOrCreatePackageStats(pkgName);
23594     }
23595
23596     public void deleteCompilerPackageStats(String pkgName) {
23597         mCompilerStats.deletePackageStats(pkgName);
23598     }
23599
23600     @Override
23601     public int getInstallReason(String packageName, int userId) {
23602         enforceCrossUserPermission(Binder.getCallingUid(), userId,
23603                 true /* requireFullPermission */, false /* checkShell */,
23604                 "get install reason");
23605         synchronized (mPackages) {
23606             final PackageSetting ps = mSettings.mPackages.get(packageName);
23607             if (ps != null) {
23608                 return ps.getInstallReason(userId);
23609             }
23610         }
23611         return PackageManager.INSTALL_REASON_UNKNOWN;
23612     }
23613
23614     @Override
23615     public boolean canRequestPackageInstalls(String packageName, int userId) {
23616         int callingUid = Binder.getCallingUid();
23617         int uid = getPackageUid(packageName, 0, userId);
23618         if (callingUid != uid && callingUid != Process.ROOT_UID
23619                 && callingUid != Process.SYSTEM_UID) {
23620             throw new SecurityException(
23621                     "Caller uid " + callingUid + " does not own package " + packageName);
23622         }
23623         ApplicationInfo info = getApplicationInfo(packageName, 0, userId);
23624         if (info == null) {
23625             return false;
23626         }
23627         if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23628             throw new UnsupportedOperationException(
23629                     "Operation only supported on apps targeting Android O or higher");
23630         }
23631         String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23632         String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23633         if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23634             throw new SecurityException("Need to declare " + appOpPermission + " to call this api");
23635         }
23636         if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23637             return false;
23638         }
23639         if (mExternalSourcesPolicy != null) {
23640             int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23641             if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23642                 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23643             }
23644         }
23645         return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23646     }
23647
23648     @Override
23649     public ComponentName getInstantAppResolverSettingsComponent() {
23650         return mInstantAppResolverSettingsComponent;
23651     }
23652
23653     @Override
23654     public ComponentName getInstantAppInstallerComponent() {
23655         return mInstantAppInstallerActivity == null
23656                 ? null : mInstantAppInstallerActivity.getComponentName();
23657     }
23658 }
23659
23660 interface PackageSender {
23661     void sendPackageBroadcast(final String action, final String pkg,
23662         final Bundle extras, final int flags, final String targetPkg,
23663         final IIntentReceiver finishedReceiver, final int[] userIds);
23664     void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
23665         int appId, int... userIds);
23666 }