OSDN Git Service

[automerger] Permission Check For DPM.getPermittedAccessibilityServices am: 4fd13eefc...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / pm / PackageManagerService.java
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.pm;
18
19 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
21 import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
27 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
28 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
29 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
30 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
31 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
33 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
34 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
35 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
36 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
37 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
38 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
39 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
53 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
54 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
55 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
56 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
57 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
58 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
59 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
60 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
61 import static android.content.pm.PackageManager.MATCH_ALL;
62 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
63 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
64 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
65 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
66 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
67 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
68 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
69 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
70 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
71 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
72 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
73 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
74 import static android.content.pm.PackageManager.PERMISSION_DENIED;
75 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
76 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
77 import static android.content.pm.PackageParser.isApkFile;
78 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
79 import static android.system.OsConstants.O_CREAT;
80 import static android.system.OsConstants.O_RDWR;
81
82 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
83 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
84 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
85 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
86 import static com.android.internal.util.ArrayUtils.appendInt;
87 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
88 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
89 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
90 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
91 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
92 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
93 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
94 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
95 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
96 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
97 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
98 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
99
100 import android.Manifest;
101 import android.annotation.NonNull;
102 import android.annotation.Nullable;
103 import android.app.ActivityManager;
104 import android.app.ActivityManagerNative;
105 import android.app.IActivityManager;
106 import android.app.ResourcesManager;
107 import android.app.admin.IDevicePolicyManager;
108 import android.app.admin.SecurityLog;
109 import android.app.backup.IBackupManager;
110 import android.content.BroadcastReceiver;
111 import android.content.ComponentName;
112 import android.content.ContentResolver;
113 import android.content.Context;
114 import android.content.IIntentReceiver;
115 import android.content.Intent;
116 import android.content.IntentFilter;
117 import android.content.IntentSender;
118 import android.content.IntentSender.SendIntentException;
119 import android.content.ServiceConnection;
120 import android.content.pm.ActivityInfo;
121 import android.content.pm.ApplicationInfo;
122 import android.content.pm.AppsQueryHelper;
123 import android.content.pm.ComponentInfo;
124 import android.content.pm.EphemeralApplicationInfo;
125 import android.content.pm.EphemeralResolveInfo;
126 import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
127 import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
128 import android.content.pm.FeatureInfo;
129 import android.content.pm.IOnPermissionsChangeListener;
130 import android.content.pm.IPackageDataObserver;
131 import android.content.pm.IPackageDeleteObserver;
132 import android.content.pm.IPackageDeleteObserver2;
133 import android.content.pm.IPackageInstallObserver2;
134 import android.content.pm.IPackageInstaller;
135 import android.content.pm.IPackageManager;
136 import android.content.pm.IPackageMoveObserver;
137 import android.content.pm.IPackageStatsObserver;
138 import android.content.pm.InstrumentationInfo;
139 import android.content.pm.IntentFilterVerificationInfo;
140 import android.content.pm.KeySet;
141 import android.content.pm.PackageCleanItem;
142 import android.content.pm.PackageInfo;
143 import android.content.pm.PackageInfoLite;
144 import android.content.pm.PackageInstaller;
145 import android.content.pm.PackageManager;
146 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
147 import android.content.pm.PackageManagerInternal;
148 import android.content.pm.PackageParser;
149 import android.content.pm.PackageParser.ActivityIntentInfo;
150 import android.content.pm.PackageParser.PackageLite;
151 import android.content.pm.PackageParser.PackageParserException;
152 import android.content.pm.PackageStats;
153 import android.content.pm.PackageUserState;
154 import android.content.pm.ParceledListSlice;
155 import android.content.pm.PermissionGroupInfo;
156 import android.content.pm.PermissionInfo;
157 import android.content.pm.ProviderInfo;
158 import android.content.pm.ResolveInfo;
159 import android.content.pm.ServiceInfo;
160 import android.content.pm.Signature;
161 import android.content.pm.UserInfo;
162 import android.content.pm.VerifierDeviceIdentity;
163 import android.content.pm.VerifierInfo;
164 import android.content.res.Resources;
165 import android.graphics.Bitmap;
166 import android.hardware.display.DisplayManager;
167 import android.net.Uri;
168 import android.os.AsyncTask;
169 import android.os.Binder;
170 import android.os.Build;
171 import android.os.Bundle;
172 import android.os.Debug;
173 import android.os.Environment;
174 import android.os.Environment.UserEnvironment;
175 import android.os.FileUtils;
176 import android.os.Handler;
177 import android.os.IBinder;
178 import android.os.Looper;
179 import android.os.Message;
180 import android.os.Parcel;
181 import android.os.ParcelFileDescriptor;
182 import android.os.PatternMatcher;
183 import android.os.Process;
184 import android.os.RemoteCallbackList;
185 import android.os.RemoteException;
186 import android.os.ResultReceiver;
187 import android.os.SELinux;
188 import android.os.ServiceManager;
189 import android.os.SystemClock;
190 import android.os.SystemProperties;
191 import android.os.Trace;
192 import android.os.UserHandle;
193 import android.os.UserManager;
194 import android.os.UserManagerInternal;
195 import android.os.storage.IMountService;
196 import android.os.storage.MountServiceInternal;
197 import android.os.storage.StorageEventListener;
198 import android.os.storage.StorageManager;
199 import android.os.storage.VolumeInfo;
200 import android.os.storage.VolumeRecord;
201 import android.provider.Settings.Global;
202 import android.provider.Settings.Secure;
203 import android.security.KeyStore;
204 import android.security.SystemKeyStore;
205 import android.system.ErrnoException;
206 import android.system.Os;
207 import android.text.TextUtils;
208 import android.text.format.DateUtils;
209 import android.util.ArrayMap;
210 import android.util.ArraySet;
211 import android.util.DisplayMetrics;
212 import android.util.EventLog;
213 import android.util.ExceptionUtils;
214 import android.util.Log;
215 import android.util.LogPrinter;
216 import android.util.MathUtils;
217 import android.util.Pair;
218 import android.util.PrintStreamPrinter;
219 import android.util.Slog;
220 import android.util.SparseArray;
221 import android.util.SparseBooleanArray;
222 import android.util.SparseIntArray;
223 import android.util.Xml;
224 import android.util.jar.StrictJarFile;
225 import android.view.Display;
226
227 import com.android.internal.R;
228 import com.android.internal.annotations.GuardedBy;
229 import com.android.internal.app.IMediaContainerService;
230 import com.android.internal.app.ResolverActivity;
231 import com.android.internal.content.NativeLibraryHelper;
232 import com.android.internal.content.PackageHelper;
233 import com.android.internal.logging.MetricsLogger;
234 import com.android.internal.os.IParcelFileDescriptorFactory;
235 import com.android.internal.os.InstallerConnection.InstallerException;
236 import com.android.internal.os.SomeArgs;
237 import com.android.internal.os.Zygote;
238 import com.android.internal.telephony.CarrierAppUtils;
239 import com.android.internal.util.ArrayUtils;
240 import com.android.internal.util.FastPrintWriter;
241 import com.android.internal.util.FastXmlSerializer;
242 import com.android.internal.util.IndentingPrintWriter;
243 import com.android.internal.util.Preconditions;
244 import com.android.internal.util.XmlUtils;
245 import com.android.server.AttributeCache;
246 import com.android.server.EventLogTags;
247 import com.android.server.FgThread;
248 import com.android.server.IntentResolver;
249 import com.android.server.LocalServices;
250 import com.android.server.ServiceThread;
251 import com.android.server.SystemConfig;
252 import com.android.server.Watchdog;
253 import com.android.server.net.NetworkPolicyManagerInternal;
254 import com.android.server.pm.PermissionsState.PermissionState;
255 import com.android.server.pm.Settings.DatabaseVersion;
256 import com.android.server.pm.Settings.VersionInfo;
257 import com.android.server.storage.DeviceStorageMonitorInternal;
258
259 import dalvik.system.CloseGuard;
260 import dalvik.system.DexFile;
261 import dalvik.system.VMRuntime;
262
263 import libcore.io.IoUtils;
264 import libcore.util.EmptyArray;
265
266 import org.xmlpull.v1.XmlPullParser;
267 import org.xmlpull.v1.XmlPullParserException;
268 import org.xmlpull.v1.XmlSerializer;
269
270 import java.io.BufferedOutputStream;
271 import java.io.BufferedReader;
272 import java.io.ByteArrayInputStream;
273 import java.io.ByteArrayOutputStream;
274 import java.io.File;
275 import java.io.FileDescriptor;
276 import java.io.FileInputStream;
277 import java.io.FileNotFoundException;
278 import java.io.FileOutputStream;
279 import java.io.FileReader;
280 import java.io.FilenameFilter;
281 import java.io.IOException;
282 import java.io.PrintWriter;
283 import java.nio.charset.StandardCharsets;
284 import java.security.DigestInputStream;
285 import java.security.MessageDigest;
286 import java.security.NoSuchAlgorithmException;
287 import java.security.PublicKey;
288 import java.security.cert.Certificate;
289 import java.security.cert.CertificateEncodingException;
290 import java.security.cert.CertificateException;
291 import java.text.SimpleDateFormat;
292 import java.util.ArrayList;
293 import java.util.Arrays;
294 import java.util.Collection;
295 import java.util.Collections;
296 import java.util.Comparator;
297 import java.util.Date;
298 import java.util.HashSet;
299 import java.util.Iterator;
300 import java.util.List;
301 import java.util.Map;
302 import java.util.Objects;
303 import java.util.Set;
304 import java.util.concurrent.CountDownLatch;
305 import java.util.concurrent.TimeUnit;
306 import java.util.concurrent.atomic.AtomicBoolean;
307 import java.util.concurrent.atomic.AtomicInteger;
308
309 /**
310  * Keep track of all those APKs everywhere.
311  * <p>
312  * Internally there are two important locks:
313  * <ul>
314  * <li>{@link #mPackages} is used to guard all in-memory parsed package details
315  * and other related state. It is a fine-grained lock that should only be held
316  * momentarily, as it's one of the most contended locks in the system.
317  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
318  * operations typically involve heavy lifting of application data on disk. Since
319  * {@code installd} is single-threaded, and it's operations can often be slow,
320  * this lock should never be acquired while already holding {@link #mPackages}.
321  * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
322  * holding {@link #mInstallLock}.
323  * </ul>
324  * Many internal methods rely on the caller to hold the appropriate locks, and
325  * this contract is expressed through method name suffixes:
326  * <ul>
327  * <li>fooLI(): the caller must hold {@link #mInstallLock}
328  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
329  * being modified must be frozen
330  * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
331  * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
332  * </ul>
333  * <p>
334  * Because this class is very central to the platform's security; please run all
335  * CTS and unit tests whenever making modifications:
336  *
337  * <pre>
338  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
339  * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
340  * </pre>
341  */
342 public class PackageManagerService extends IPackageManager.Stub {
343     static final String TAG = "PackageManager";
344     static final boolean DEBUG_SETTINGS = false;
345     static final boolean DEBUG_PREFERRED = false;
346     static final boolean DEBUG_UPGRADE = false;
347     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
348     private static final boolean DEBUG_BACKUP = false;
349     private static final boolean DEBUG_INSTALL = false;
350     private static final boolean DEBUG_REMOVE = false;
351     private static final boolean DEBUG_BROADCASTS = false;
352     private static final boolean DEBUG_SHOW_INFO = false;
353     private static final boolean DEBUG_PACKAGE_INFO = false;
354     private static final boolean DEBUG_INTENT_MATCHING = false;
355     private static final boolean DEBUG_PACKAGE_SCANNING = false;
356     private static final boolean DEBUG_VERIFY = false;
357     private static final boolean DEBUG_FILTERS = false;
358
359     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
360     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
361     // user, but by default initialize to this.
362     static final boolean DEBUG_DEXOPT = false;
363
364     private static final boolean DEBUG_ABI_SELECTION = false;
365     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
366     private static final boolean DEBUG_TRIAGED_MISSING = false;
367     private static final boolean DEBUG_APP_DATA = false;
368
369     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
370
371     private static final boolean DISABLE_EPHEMERAL_APPS = false;
372     private static final boolean HIDE_EPHEMERAL_APIS = true;
373
374     private static final int RADIO_UID = Process.PHONE_UID;
375     private static final int LOG_UID = Process.LOG_UID;
376     private static final int NFC_UID = Process.NFC_UID;
377     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
378     private static final int SHELL_UID = Process.SHELL_UID;
379
380     // Cap the size of permission trees that 3rd party apps can define
381     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
382
383     // Suffix used during package installation when copying/moving
384     // package apks to install directory.
385     private static final String INSTALL_PACKAGE_SUFFIX = "-";
386
387     static final int SCAN_NO_DEX = 1<<1;
388     static final int SCAN_FORCE_DEX = 1<<2;
389     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
390     static final int SCAN_NEW_INSTALL = 1<<4;
391     static final int SCAN_NO_PATHS = 1<<5;
392     static final int SCAN_UPDATE_TIME = 1<<6;
393     static final int SCAN_DEFER_DEX = 1<<7;
394     static final int SCAN_BOOTING = 1<<8;
395     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
396     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
397     static final int SCAN_REPLACING = 1<<11;
398     static final int SCAN_REQUIRE_KNOWN = 1<<12;
399     static final int SCAN_MOVE = 1<<13;
400     static final int SCAN_INITIAL = 1<<14;
401     static final int SCAN_CHECK_ONLY = 1<<15;
402     static final int SCAN_DONT_KILL_APP = 1<<17;
403     static final int SCAN_IGNORE_FROZEN = 1<<18;
404
405     static final int REMOVE_CHATTY = 1<<16;
406
407     private static final int[] EMPTY_INT_ARRAY = new int[0];
408
409     /**
410      * Timeout (in milliseconds) after which the watchdog should declare that
411      * our handler thread is wedged.  The usual default for such things is one
412      * minute but we sometimes do very lengthy I/O operations on this thread,
413      * such as installing multi-gigabyte applications, so ours needs to be longer.
414      */
415     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
416
417     /**
418      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
419      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
420      * settings entry if available, otherwise we use the hardcoded default.  If it's been
421      * more than this long since the last fstrim, we force one during the boot sequence.
422      *
423      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
424      * one gets run at the next available charging+idle time.  This final mandatory
425      * no-fstrim check kicks in only of the other scheduling criteria is never met.
426      */
427     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
428
429     /**
430      * Whether verification is enabled by default.
431      */
432     private static final boolean DEFAULT_VERIFY_ENABLE = true;
433
434     /**
435      * The default maximum time to wait for the verification agent to return in
436      * milliseconds.
437      */
438     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
439
440     /**
441      * The default response for package verification timeout.
442      *
443      * This can be either PackageManager.VERIFICATION_ALLOW or
444      * PackageManager.VERIFICATION_REJECT.
445      */
446     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
447
448     static final String PLATFORM_PACKAGE_NAME = "android";
449
450     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
451
452     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
453             DEFAULT_CONTAINER_PACKAGE,
454             "com.android.defcontainer.DefaultContainerService");
455
456     private static final String KILL_APP_REASON_GIDS_CHANGED =
457             "permission grant or revoke changed gids";
458
459     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
460             "permissions revoked";
461
462     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
463
464     private static final String PACKAGE_SCHEME = "package";
465
466     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
467     /**
468      * If VENDOR_OVERLAY_THEME_PROPERTY is set, search for runtime resource overlay APKs also in
469      * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_THEME_PROPERTY> in addition to
470      * VENDOR_OVERLAY_DIR.
471      */
472     private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme";
473
474     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000;
475     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5;
476
477     /** Permission grant: not grant the permission. */
478     private static final int GRANT_DENIED = 1;
479
480     /** Permission grant: grant the permission as an install permission. */
481     private static final int GRANT_INSTALL = 2;
482
483     /** Permission grant: grant the permission as a runtime one. */
484     private static final int GRANT_RUNTIME = 3;
485
486     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
487     private static final int GRANT_UPGRADE = 4;
488
489     /** Canonical intent used to identify what counts as a "web browser" app */
490     private static final Intent sBrowserIntent;
491     static {
492         sBrowserIntent = new Intent();
493         sBrowserIntent.setAction(Intent.ACTION_VIEW);
494         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
495         sBrowserIntent.setData(Uri.parse("http:"));
496     }
497
498     /**
499      * The set of all protected actions [i.e. those actions for which a high priority
500      * intent filter is disallowed].
501      */
502     private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
503     static {
504         PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
505         PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
506         PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
507         PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
508     }
509
510     // Compilation reasons.
511     public static final int REASON_FIRST_BOOT = 0;
512     public static final int REASON_BOOT = 1;
513     public static final int REASON_INSTALL = 2;
514     public static final int REASON_BACKGROUND_DEXOPT = 3;
515     public static final int REASON_AB_OTA = 4;
516     public static final int REASON_NON_SYSTEM_LIBRARY = 5;
517     public static final int REASON_SHARED_APK = 6;
518     public static final int REASON_FORCED_DEXOPT = 7;
519     public static final int REASON_CORE_APP = 8;
520
521     public static final int REASON_LAST = REASON_CORE_APP;
522
523     /** Special library name that skips shared libraries check during compilation. */
524     private static final String SKIP_SHARED_LIBRARY_CHECK = "&";
525
526     final ServiceThread mHandlerThread;
527
528     final PackageHandler mHandler;
529
530     private final ProcessLoggingHandler mProcessLoggingHandler;
531
532     /**
533      * Messages for {@link #mHandler} that need to wait for system ready before
534      * being dispatched.
535      */
536     private ArrayList<Message> mPostSystemReadyMessages;
537
538     final int mSdkVersion = Build.VERSION.SDK_INT;
539
540     final Context mContext;
541     final boolean mFactoryTest;
542     final boolean mOnlyCore;
543     final DisplayMetrics mMetrics;
544     final int mDefParseFlags;
545     final String[] mSeparateProcesses;
546     final boolean mIsUpgrade;
547     final boolean mIsPreNUpgrade;
548     final boolean mIsPreNMR1Upgrade;
549
550     @GuardedBy("mPackages")
551     private boolean mDexOptDialogShown;
552
553     /** The location for ASEC container files on internal storage. */
554     final String mAsecInternalPath;
555
556     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
557     // LOCK HELD.  Can be called with mInstallLock held.
558     @GuardedBy("mInstallLock")
559     final Installer mInstaller;
560
561     /** Directory where installed third-party apps stored */
562     final File mAppInstallDir;
563     final File mEphemeralInstallDir;
564
565     /**
566      * Directory to which applications installed internally have their
567      * 32 bit native libraries copied.
568      */
569     private File mAppLib32InstallDir;
570
571     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
572     // apps.
573     final File mDrmAppPrivateInstallDir;
574
575     // ----------------------------------------------------------------
576
577     // Lock for state used when installing and doing other long running
578     // operations.  Methods that must be called with this lock held have
579     // the suffix "LI".
580     final Object mInstallLock = new Object();
581
582     // ----------------------------------------------------------------
583
584     // Keys are String (package name), values are Package.  This also serves
585     // as the lock for the global state.  Methods that must be called with
586     // this lock held have the prefix "LP".
587     @GuardedBy("mPackages")
588     final ArrayMap<String, PackageParser.Package> mPackages =
589             new ArrayMap<String, PackageParser.Package>();
590
591     final ArrayMap<String, Set<String>> mKnownCodebase =
592             new ArrayMap<String, Set<String>>();
593
594     // Tracks available target package names -> overlay package paths.
595     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
596         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
597
598     /**
599      * Tracks new system packages [received in an OTA] that we expect to
600      * find updated user-installed versions. Keys are package name, values
601      * are package location.
602      */
603     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
604     /**
605      * Tracks high priority intent filters for protected actions. During boot, certain
606      * filter actions are protected and should never be allowed to have a high priority
607      * intent filter for them. However, there is one, and only one exception -- the
608      * setup wizard. It must be able to define a high priority intent filter for these
609      * actions to ensure there are no escapes from the wizard. We need to delay processing
610      * of these during boot as we need to look at all of the system packages in order
611      * to know which component is the setup wizard.
612      */
613     private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
614     /**
615      * Whether or not processing protected filters should be deferred.
616      */
617     private boolean mDeferProtectedFilters = true;
618
619     /**
620      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
621      */
622     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
623     /**
624      * Whether or not system app permissions should be promoted from install to runtime.
625      */
626     boolean mPromoteSystemApps;
627
628     @GuardedBy("mPackages")
629     final Settings mSettings;
630
631     /**
632      * Set of package names that are currently "frozen", which means active
633      * surgery is being done on the code/data for that package. The platform
634      * will refuse to launch frozen packages to avoid race conditions.
635      *
636      * @see PackageFreezer
637      */
638     @GuardedBy("mPackages")
639     final ArraySet<String> mFrozenPackages = new ArraySet<>();
640
641     final ProtectedPackages mProtectedPackages;
642
643     boolean mFirstBoot;
644
645     // System configuration read by SystemConfig.
646     final int[] mGlobalGids;
647     final SparseArray<ArraySet<String>> mSystemPermissions;
648     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
649
650     // If mac_permissions.xml was found for seinfo labeling.
651     boolean mFoundPolicyFile;
652
653     private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
654
655     public static final class SharedLibraryEntry {
656         public final String path;
657         public final String apk;
658
659         SharedLibraryEntry(String _path, String _apk) {
660             path = _path;
661             apk = _apk;
662         }
663     }
664
665     // Currently known shared libraries.
666     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
667             new ArrayMap<String, SharedLibraryEntry>();
668
669     // All available activities, for your resolving pleasure.
670     final ActivityIntentResolver mActivities =
671             new ActivityIntentResolver();
672
673     // All available receivers, for your resolving pleasure.
674     final ActivityIntentResolver mReceivers =
675             new ActivityIntentResolver();
676
677     // All available services, for your resolving pleasure.
678     final ServiceIntentResolver mServices = new ServiceIntentResolver();
679
680     // All available providers, for your resolving pleasure.
681     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
682
683     // Mapping from provider base names (first directory in content URI codePath)
684     // to the provider information.
685     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
686             new ArrayMap<String, PackageParser.Provider>();
687
688     // Mapping from instrumentation class names to info about them.
689     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
690             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
691
692     // Mapping from permission names to info about them.
693     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
694             new ArrayMap<String, PackageParser.PermissionGroup>();
695
696     // Packages whose data we have transfered into another package, thus
697     // should no longer exist.
698     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
699
700     // Broadcast actions that are only available to the system.
701     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
702
703     /** List of packages waiting for verification. */
704     final SparseArray<PackageVerificationState> mPendingVerification
705             = new SparseArray<PackageVerificationState>();
706
707     /** Set of packages associated with each app op permission. */
708     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
709
710     final PackageInstallerService mInstallerService;
711
712     private final PackageDexOptimizer mPackageDexOptimizer;
713
714     private AtomicInteger mNextMoveId = new AtomicInteger();
715     private final MoveCallbacks mMoveCallbacks;
716
717     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
718
719     // Cache of users who need badging.
720     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
721
722     /** Token for keys in mPendingVerification. */
723     private int mPendingVerificationToken = 0;
724
725     volatile boolean mSystemReady;
726     volatile boolean mSafeMode;
727     volatile boolean mHasSystemUidErrors;
728
729     ApplicationInfo mAndroidApplication;
730     final ActivityInfo mResolveActivity = new ActivityInfo();
731     final ResolveInfo mResolveInfo = new ResolveInfo();
732     ComponentName mResolveComponentName;
733     PackageParser.Package mPlatformPackage;
734     ComponentName mCustomResolverComponentName;
735
736     boolean mResolverReplaced = false;
737
738     private final @Nullable ComponentName mIntentFilterVerifierComponent;
739     private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
740
741     private int mIntentFilterVerificationToken = 0;
742
743     /** Component that knows whether or not an ephemeral application exists */
744     final ComponentName mEphemeralResolverComponent;
745     /** The service connection to the ephemeral resolver */
746     final EphemeralResolverConnection mEphemeralResolverConnection;
747
748     /** Component used to install ephemeral applications */
749     final ComponentName mEphemeralInstallerComponent;
750     final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
751     final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
752
753     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
754             = new SparseArray<IntentFilterVerificationState>();
755
756     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
757
758     // List of packages names to keep cached, even if they are uninstalled for all users
759     private List<String> mKeepUninstalledPackages;
760
761     private UserManagerInternal mUserManagerInternal;
762
763     private static class IFVerificationParams {
764         PackageParser.Package pkg;
765         boolean replacing;
766         int userId;
767         int verifierUid;
768
769         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
770                 int _userId, int _verifierUid) {
771             pkg = _pkg;
772             replacing = _replacing;
773             userId = _userId;
774             replacing = _replacing;
775             verifierUid = _verifierUid;
776         }
777     }
778
779     private interface IntentFilterVerifier<T extends IntentFilter> {
780         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
781                                                T filter, String packageName);
782         void startVerifications(int userId);
783         void receiveVerificationResponse(int verificationId);
784     }
785
786     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
787         private Context mContext;
788         private ComponentName mIntentFilterVerifierComponent;
789         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
790
791         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
792             mContext = context;
793             mIntentFilterVerifierComponent = verifierComponent;
794         }
795
796         private String getDefaultScheme() {
797             return IntentFilter.SCHEME_HTTPS;
798         }
799
800         @Override
801         public void startVerifications(int userId) {
802             // Launch verifications requests
803             int count = mCurrentIntentFilterVerifications.size();
804             for (int n=0; n<count; n++) {
805                 int verificationId = mCurrentIntentFilterVerifications.get(n);
806                 final IntentFilterVerificationState ivs =
807                         mIntentFilterVerificationStates.get(verificationId);
808
809                 String packageName = ivs.getPackageName();
810
811                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
812                 final int filterCount = filters.size();
813                 ArraySet<String> domainsSet = new ArraySet<>();
814                 for (int m=0; m<filterCount; m++) {
815                     PackageParser.ActivityIntentInfo filter = filters.get(m);
816                     domainsSet.addAll(filter.getHostsList());
817                 }
818                 ArrayList<String> domainsList = new ArrayList<>(domainsSet);
819                 synchronized (mPackages) {
820                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
821                             packageName, domainsList) != null) {
822                         scheduleWriteSettingsLocked();
823                     }
824                 }
825                 sendVerificationRequest(userId, verificationId, ivs);
826             }
827             mCurrentIntentFilterVerifications.clear();
828         }
829
830         private void sendVerificationRequest(int userId, int verificationId,
831                 IntentFilterVerificationState ivs) {
832
833             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
834             verificationIntent.putExtra(
835                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
836                     verificationId);
837             verificationIntent.putExtra(
838                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
839                     getDefaultScheme());
840             verificationIntent.putExtra(
841                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
842                     ivs.getHostsString());
843             verificationIntent.putExtra(
844                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
845                     ivs.getPackageName());
846             verificationIntent.setComponent(mIntentFilterVerifierComponent);
847             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
848
849             UserHandle user = new UserHandle(userId);
850             mContext.sendBroadcastAsUser(verificationIntent, user);
851             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
852                     "Sending IntentFilter verification broadcast");
853         }
854
855         public void receiveVerificationResponse(int verificationId) {
856             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
857
858             final boolean verified = ivs.isVerified();
859
860             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
861             final int count = filters.size();
862             if (DEBUG_DOMAIN_VERIFICATION) {
863                 Slog.i(TAG, "Received verification response " + verificationId
864                         + " for " + count + " filters, verified=" + verified);
865             }
866             for (int n=0; n<count; n++) {
867                 PackageParser.ActivityIntentInfo filter = filters.get(n);
868                 filter.setVerified(verified);
869
870                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
871                         + " verified with result:" + verified + " and hosts:"
872                         + ivs.getHostsString());
873             }
874
875             mIntentFilterVerificationStates.remove(verificationId);
876
877             final String packageName = ivs.getPackageName();
878             IntentFilterVerificationInfo ivi = null;
879
880             synchronized (mPackages) {
881                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
882             }
883             if (ivi == null) {
884                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
885                         + verificationId + " packageName:" + packageName);
886                 return;
887             }
888             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
889                     "Updating IntentFilterVerificationInfo for package " + packageName
890                             +" verificationId:" + verificationId);
891
892             synchronized (mPackages) {
893                 if (verified) {
894                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
895                 } else {
896                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
897                 }
898                 scheduleWriteSettingsLocked();
899
900                 final int userId = ivs.getUserId();
901                 if (userId != UserHandle.USER_ALL) {
902                     final int userStatus =
903                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
904
905                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
906                     boolean needUpdate = false;
907
908                     // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
909                     // already been set by the User thru the Disambiguation dialog
910                     switch (userStatus) {
911                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
912                             if (verified) {
913                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
914                             } else {
915                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
916                             }
917                             needUpdate = true;
918                             break;
919
920                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
921                             if (verified) {
922                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
923                                 needUpdate = true;
924                             }
925                             break;
926
927                         default:
928                             // Nothing to do
929                     }
930
931                     if (needUpdate) {
932                         mSettings.updateIntentFilterVerificationStatusLPw(
933                                 packageName, updatedStatus, userId);
934                         scheduleWritePackageRestrictionsLocked(userId);
935                     }
936                 }
937             }
938         }
939
940         @Override
941         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
942                     ActivityIntentInfo filter, String packageName) {
943             if (!hasValidDomains(filter)) {
944                 return false;
945             }
946             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
947             if (ivs == null) {
948                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
949                         packageName);
950             }
951             if (DEBUG_DOMAIN_VERIFICATION) {
952                 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
953             }
954             ivs.addFilter(filter);
955             return true;
956         }
957
958         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
959                 int userId, int verificationId, String packageName) {
960             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
961                     verifierUid, userId, packageName);
962             ivs.setPendingState();
963             synchronized (mPackages) {
964                 mIntentFilterVerificationStates.append(verificationId, ivs);
965                 mCurrentIntentFilterVerifications.add(verificationId);
966             }
967             return ivs;
968         }
969     }
970
971     private static boolean hasValidDomains(ActivityIntentInfo filter) {
972         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
973                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
974                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
975     }
976
977     // Set of pending broadcasts for aggregating enable/disable of components.
978     static class PendingPackageBroadcasts {
979         // for each user id, a map of <package name -> components within that package>
980         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
981
982         public PendingPackageBroadcasts() {
983             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
984         }
985
986         public ArrayList<String> get(int userId, String packageName) {
987             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
988             return packages.get(packageName);
989         }
990
991         public void put(int userId, String packageName, ArrayList<String> components) {
992             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
993             packages.put(packageName, components);
994         }
995
996         public void remove(int userId, String packageName) {
997             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
998             if (packages != null) {
999                 packages.remove(packageName);
1000             }
1001         }
1002
1003         public void remove(int userId) {
1004             mUidMap.remove(userId);
1005         }
1006
1007         public int userIdCount() {
1008             return mUidMap.size();
1009         }
1010
1011         public int userIdAt(int n) {
1012             return mUidMap.keyAt(n);
1013         }
1014
1015         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1016             return mUidMap.get(userId);
1017         }
1018
1019         public int size() {
1020             // total number of pending broadcast entries across all userIds
1021             int num = 0;
1022             for (int i = 0; i< mUidMap.size(); i++) {
1023                 num += mUidMap.valueAt(i).size();
1024             }
1025             return num;
1026         }
1027
1028         public void clear() {
1029             mUidMap.clear();
1030         }
1031
1032         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1033             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1034             if (map == null) {
1035                 map = new ArrayMap<String, ArrayList<String>>();
1036                 mUidMap.put(userId, map);
1037             }
1038             return map;
1039         }
1040     }
1041     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1042
1043     // Service Connection to remote media container service to copy
1044     // package uri's from external media onto secure containers
1045     // or internal storage.
1046     private IMediaContainerService mContainerService = null;
1047
1048     static final int SEND_PENDING_BROADCAST = 1;
1049     static final int MCS_BOUND = 3;
1050     static final int END_COPY = 4;
1051     static final int INIT_COPY = 5;
1052     static final int MCS_UNBIND = 6;
1053     static final int START_CLEANING_PACKAGE = 7;
1054     static final int FIND_INSTALL_LOC = 8;
1055     static final int POST_INSTALL = 9;
1056     static final int MCS_RECONNECT = 10;
1057     static final int MCS_GIVE_UP = 11;
1058     static final int UPDATED_MEDIA_STATUS = 12;
1059     static final int WRITE_SETTINGS = 13;
1060     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1061     static final int PACKAGE_VERIFIED = 15;
1062     static final int CHECK_PENDING_VERIFICATION = 16;
1063     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1064     static final int INTENT_FILTER_VERIFIED = 18;
1065     static final int WRITE_PACKAGE_LIST = 19;
1066
1067     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1068
1069     // Delay time in millisecs
1070     static final int BROADCAST_DELAY = 10 * 1000;
1071
1072     static UserManagerService sUserManager;
1073
1074     // Stores a list of users whose package restrictions file needs to be updated
1075     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1076
1077     final private DefaultContainerConnection mDefContainerConn =
1078             new DefaultContainerConnection();
1079     class DefaultContainerConnection implements ServiceConnection {
1080         public void onServiceConnected(ComponentName name, IBinder service) {
1081             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1082             IMediaContainerService imcs =
1083                 IMediaContainerService.Stub.asInterface(service);
1084             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1085         }
1086
1087         public void onServiceDisconnected(ComponentName name) {
1088             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1089         }
1090     }
1091
1092     // Recordkeeping of restore-after-install operations that are currently in flight
1093     // between the Package Manager and the Backup Manager
1094     static class PostInstallData {
1095         public InstallArgs args;
1096         public PackageInstalledInfo res;
1097
1098         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1099             args = _a;
1100             res = _r;
1101         }
1102     }
1103
1104     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1105     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1106
1107     // XML tags for backup/restore of various bits of state
1108     private static final String TAG_PREFERRED_BACKUP = "pa";
1109     private static final String TAG_DEFAULT_APPS = "da";
1110     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1111
1112     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1113     private static final String TAG_ALL_GRANTS = "rt-grants";
1114     private static final String TAG_GRANT = "grant";
1115     private static final String ATTR_PACKAGE_NAME = "pkg";
1116
1117     private static final String TAG_PERMISSION = "perm";
1118     private static final String ATTR_PERMISSION_NAME = "name";
1119     private static final String ATTR_IS_GRANTED = "g";
1120     private static final String ATTR_USER_SET = "set";
1121     private static final String ATTR_USER_FIXED = "fixed";
1122     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1123
1124     // System/policy permission grants are not backed up
1125     private static final int SYSTEM_RUNTIME_GRANT_MASK =
1126             FLAG_PERMISSION_POLICY_FIXED
1127             | FLAG_PERMISSION_SYSTEM_FIXED
1128             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1129
1130     // And we back up these user-adjusted states
1131     private static final int USER_RUNTIME_GRANT_MASK =
1132             FLAG_PERMISSION_USER_SET
1133             | FLAG_PERMISSION_USER_FIXED
1134             | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1135
1136     final @Nullable String mRequiredVerifierPackage;
1137     final @NonNull String mRequiredInstallerPackage;
1138     final @NonNull String mRequiredUninstallerPackage;
1139     final @Nullable String mSetupWizardPackage;
1140     final @Nullable String mStorageManagerPackage;
1141     final @NonNull String mServicesSystemSharedLibraryPackageName;
1142     final @NonNull String mSharedSystemSharedLibraryPackageName;
1143
1144     final boolean mPermissionReviewRequired;
1145
1146     private final PackageUsage mPackageUsage = new PackageUsage();
1147     private final CompilerStats mCompilerStats = new CompilerStats();
1148
1149     class PackageHandler extends Handler {
1150         private boolean mBound = false;
1151         final ArrayList<HandlerParams> mPendingInstalls =
1152             new ArrayList<HandlerParams>();
1153
1154         private boolean connectToService() {
1155             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1156                     " DefaultContainerService");
1157             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1158             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1159             if (mContext.bindServiceAsUser(service, mDefContainerConn,
1160                     Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1161                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1162                 mBound = true;
1163                 return true;
1164             }
1165             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1166             return false;
1167         }
1168
1169         private void disconnectService() {
1170             mContainerService = null;
1171             mBound = false;
1172             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1173             mContext.unbindService(mDefContainerConn);
1174             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1175         }
1176
1177         PackageHandler(Looper looper) {
1178             super(looper);
1179         }
1180
1181         public void handleMessage(Message msg) {
1182             try {
1183                 doHandleMessage(msg);
1184             } finally {
1185                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1186             }
1187         }
1188
1189         void doHandleMessage(Message msg) {
1190             switch (msg.what) {
1191                 case INIT_COPY: {
1192                     HandlerParams params = (HandlerParams) msg.obj;
1193                     int idx = mPendingInstalls.size();
1194                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1195                     // If a bind was already initiated we dont really
1196                     // need to do anything. The pending install
1197                     // will be processed later on.
1198                     if (!mBound) {
1199                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1200                                 System.identityHashCode(mHandler));
1201                         // If this is the only one pending we might
1202                         // have to bind to the service again.
1203                         if (!connectToService()) {
1204                             Slog.e(TAG, "Failed to bind to media container service");
1205                             params.serviceError();
1206                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1207                                     System.identityHashCode(mHandler));
1208                             if (params.traceMethod != null) {
1209                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1210                                         params.traceCookie);
1211                             }
1212                             return;
1213                         } else {
1214                             // Once we bind to the service, the first
1215                             // pending request will be processed.
1216                             mPendingInstalls.add(idx, params);
1217                         }
1218                     } else {
1219                         mPendingInstalls.add(idx, params);
1220                         // Already bound to the service. Just make
1221                         // sure we trigger off processing the first request.
1222                         if (idx == 0) {
1223                             mHandler.sendEmptyMessage(MCS_BOUND);
1224                         }
1225                     }
1226                     break;
1227                 }
1228                 case MCS_BOUND: {
1229                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1230                     if (msg.obj != null) {
1231                         mContainerService = (IMediaContainerService) msg.obj;
1232                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1233                                 System.identityHashCode(mHandler));
1234                     }
1235                     if (mContainerService == null) {
1236                         if (!mBound) {
1237                             // Something seriously wrong since we are not bound and we are not
1238                             // waiting for connection. Bail out.
1239                             Slog.e(TAG, "Cannot bind to media container service");
1240                             for (HandlerParams params : mPendingInstalls) {
1241                                 // Indicate service bind error
1242                                 params.serviceError();
1243                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1244                                         System.identityHashCode(params));
1245                                 if (params.traceMethod != null) {
1246                                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1247                                             params.traceMethod, params.traceCookie);
1248                                 }
1249                                 return;
1250                             }
1251                             mPendingInstalls.clear();
1252                         } else {
1253                             Slog.w(TAG, "Waiting to connect to media container service");
1254                         }
1255                     } else if (mPendingInstalls.size() > 0) {
1256                         HandlerParams params = mPendingInstalls.get(0);
1257                         if (params != null) {
1258                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1259                                     System.identityHashCode(params));
1260                             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1261                             if (params.startCopy()) {
1262                                 // We are done...  look for more work or to
1263                                 // go idle.
1264                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
1265                                         "Checking for more work or unbind...");
1266                                 // Delete pending install
1267                                 if (mPendingInstalls.size() > 0) {
1268                                     mPendingInstalls.remove(0);
1269                                 }
1270                                 if (mPendingInstalls.size() == 0) {
1271                                     if (mBound) {
1272                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
1273                                                 "Posting delayed MCS_UNBIND");
1274                                         removeMessages(MCS_UNBIND);
1275                                         Message ubmsg = obtainMessage(MCS_UNBIND);
1276                                         // Unbind after a little delay, to avoid
1277                                         // continual thrashing.
1278                                         sendMessageDelayed(ubmsg, 10000);
1279                                     }
1280                                 } else {
1281                                     // There are more pending requests in queue.
1282                                     // Just post MCS_BOUND message to trigger processing
1283                                     // of next pending install.
1284                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
1285                                             "Posting MCS_BOUND for next work");
1286                                     mHandler.sendEmptyMessage(MCS_BOUND);
1287                                 }
1288                             }
1289                             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1290                         }
1291                     } else {
1292                         // Should never happen ideally.
1293                         Slog.w(TAG, "Empty queue");
1294                     }
1295                     break;
1296                 }
1297                 case MCS_RECONNECT: {
1298                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1299                     if (mPendingInstalls.size() > 0) {
1300                         if (mBound) {
1301                             disconnectService();
1302                         }
1303                         if (!connectToService()) {
1304                             Slog.e(TAG, "Failed to bind to media container service");
1305                             for (HandlerParams params : mPendingInstalls) {
1306                                 // Indicate service bind error
1307                                 params.serviceError();
1308                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1309                                         System.identityHashCode(params));
1310                             }
1311                             mPendingInstalls.clear();
1312                         }
1313                     }
1314                     break;
1315                 }
1316                 case MCS_UNBIND: {
1317                     // If there is no actual work left, then time to unbind.
1318                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1319
1320                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1321                         if (mBound) {
1322                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1323
1324                             disconnectService();
1325                         }
1326                     } else if (mPendingInstalls.size() > 0) {
1327                         // There are more pending requests in queue.
1328                         // Just post MCS_BOUND message to trigger processing
1329                         // of next pending install.
1330                         mHandler.sendEmptyMessage(MCS_BOUND);
1331                     }
1332
1333                     break;
1334                 }
1335                 case MCS_GIVE_UP: {
1336                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1337                     HandlerParams params = mPendingInstalls.remove(0);
1338                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1339                             System.identityHashCode(params));
1340                     break;
1341                 }
1342                 case SEND_PENDING_BROADCAST: {
1343                     String packages[];
1344                     ArrayList<String> components[];
1345                     int size = 0;
1346                     int uids[];
1347                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1348                     synchronized (mPackages) {
1349                         if (mPendingBroadcasts == null) {
1350                             return;
1351                         }
1352                         size = mPendingBroadcasts.size();
1353                         if (size <= 0) {
1354                             // Nothing to be done. Just return
1355                             return;
1356                         }
1357                         packages = new String[size];
1358                         components = new ArrayList[size];
1359                         uids = new int[size];
1360                         int i = 0;  // filling out the above arrays
1361
1362                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1363                             int packageUserId = mPendingBroadcasts.userIdAt(n);
1364                             Iterator<Map.Entry<String, ArrayList<String>>> it
1365                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
1366                                             .entrySet().iterator();
1367                             while (it.hasNext() && i < size) {
1368                                 Map.Entry<String, ArrayList<String>> ent = it.next();
1369                                 packages[i] = ent.getKey();
1370                                 components[i] = ent.getValue();
1371                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1372                                 uids[i] = (ps != null)
1373                                         ? UserHandle.getUid(packageUserId, ps.appId)
1374                                         : -1;
1375                                 i++;
1376                             }
1377                         }
1378                         size = i;
1379                         mPendingBroadcasts.clear();
1380                     }
1381                     // Send broadcasts
1382                     for (int i = 0; i < size; i++) {
1383                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1384                     }
1385                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1386                     break;
1387                 }
1388                 case START_CLEANING_PACKAGE: {
1389                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1390                     final String packageName = (String)msg.obj;
1391                     final int userId = msg.arg1;
1392                     final boolean andCode = msg.arg2 != 0;
1393                     synchronized (mPackages) {
1394                         if (userId == UserHandle.USER_ALL) {
1395                             int[] users = sUserManager.getUserIds();
1396                             for (int user : users) {
1397                                 mSettings.addPackageToCleanLPw(
1398                                         new PackageCleanItem(user, packageName, andCode));
1399                             }
1400                         } else {
1401                             mSettings.addPackageToCleanLPw(
1402                                     new PackageCleanItem(userId, packageName, andCode));
1403                         }
1404                     }
1405                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1406                     startCleaningPackages();
1407                 } break;
1408                 case POST_INSTALL: {
1409                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1410
1411                     PostInstallData data = mRunningInstalls.get(msg.arg1);
1412                     final boolean didRestore = (msg.arg2 != 0);
1413                     mRunningInstalls.delete(msg.arg1);
1414
1415                     if (data != null) {
1416                         InstallArgs args = data.args;
1417                         PackageInstalledInfo parentRes = data.res;
1418
1419                         final boolean grantPermissions = (args.installFlags
1420                                 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1421                         final boolean killApp = (args.installFlags
1422                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1423                         final String[] grantedPermissions = args.installGrantPermissions;
1424
1425                         // Handle the parent package
1426                         handlePackagePostInstall(parentRes, grantPermissions, killApp,
1427                                 grantedPermissions, didRestore, args.installerPackageName,
1428                                 args.observer);
1429
1430                         // Handle the child packages
1431                         final int childCount = (parentRes.addedChildPackages != null)
1432                                 ? parentRes.addedChildPackages.size() : 0;
1433                         for (int i = 0; i < childCount; i++) {
1434                             PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1435                             handlePackagePostInstall(childRes, grantPermissions, killApp,
1436                                     grantedPermissions, false, args.installerPackageName,
1437                                     args.observer);
1438                         }
1439
1440                         // Log tracing if needed
1441                         if (args.traceMethod != null) {
1442                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1443                                     args.traceCookie);
1444                         }
1445                     } else {
1446                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1447                     }
1448
1449                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1450                 } break;
1451                 case UPDATED_MEDIA_STATUS: {
1452                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1453                     boolean reportStatus = msg.arg1 == 1;
1454                     boolean doGc = msg.arg2 == 1;
1455                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1456                     if (doGc) {
1457                         // Force a gc to clear up stale containers.
1458                         Runtime.getRuntime().gc();
1459                     }
1460                     if (msg.obj != null) {
1461                         @SuppressWarnings("unchecked")
1462                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1463                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1464                         // Unload containers
1465                         unloadAllContainers(args);
1466                     }
1467                     if (reportStatus) {
1468                         try {
1469                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1470                             PackageHelper.getMountService().finishMediaUpdate();
1471                         } catch (RemoteException e) {
1472                             Log.e(TAG, "MountService not running?");
1473                         }
1474                     }
1475                 } break;
1476                 case WRITE_SETTINGS: {
1477                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1478                     synchronized (mPackages) {
1479                         removeMessages(WRITE_SETTINGS);
1480                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1481                         mSettings.writeLPr();
1482                         mDirtyUsers.clear();
1483                     }
1484                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1485                 } break;
1486                 case WRITE_PACKAGE_RESTRICTIONS: {
1487                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1488                     synchronized (mPackages) {
1489                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1490                         for (int userId : mDirtyUsers) {
1491                             mSettings.writePackageRestrictionsLPr(userId);
1492                         }
1493                         mDirtyUsers.clear();
1494                     }
1495                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1496                 } break;
1497                 case WRITE_PACKAGE_LIST: {
1498                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1499                     synchronized (mPackages) {
1500                         removeMessages(WRITE_PACKAGE_LIST);
1501                         mSettings.writePackageListLPr(msg.arg1);
1502                     }
1503                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1504                 } break;
1505                 case CHECK_PENDING_VERIFICATION: {
1506                     final int verificationId = msg.arg1;
1507                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1508
1509                     if ((state != null) && !state.timeoutExtended()) {
1510                         final InstallArgs args = state.getInstallArgs();
1511                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1512
1513                         Slog.i(TAG, "Verification timed out for " + originUri);
1514                         mPendingVerification.remove(verificationId);
1515
1516                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1517
1518                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1519                             Slog.i(TAG, "Continuing with installation of " + originUri);
1520                             state.setVerifierResponse(Binder.getCallingUid(),
1521                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1522                             broadcastPackageVerified(verificationId, originUri,
1523                                     PackageManager.VERIFICATION_ALLOW,
1524                                     state.getInstallArgs().getUser());
1525                             try {
1526                                 ret = args.copyApk(mContainerService, true);
1527                             } catch (RemoteException e) {
1528                                 Slog.e(TAG, "Could not contact the ContainerService");
1529                             }
1530                         } else {
1531                             broadcastPackageVerified(verificationId, originUri,
1532                                     PackageManager.VERIFICATION_REJECT,
1533                                     state.getInstallArgs().getUser());
1534                         }
1535
1536                         Trace.asyncTraceEnd(
1537                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1538
1539                         processPendingInstall(args, ret);
1540                         mHandler.sendEmptyMessage(MCS_UNBIND);
1541                     }
1542                     break;
1543                 }
1544                 case PACKAGE_VERIFIED: {
1545                     final int verificationId = msg.arg1;
1546
1547                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1548                     if (state == null) {
1549                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1550                         break;
1551                     }
1552
1553                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1554
1555                     state.setVerifierResponse(response.callerUid, response.code);
1556
1557                     if (state.isVerificationComplete()) {
1558                         mPendingVerification.remove(verificationId);
1559
1560                         final InstallArgs args = state.getInstallArgs();
1561                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1562
1563                         int ret;
1564                         if (state.isInstallAllowed()) {
1565                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1566                             broadcastPackageVerified(verificationId, originUri,
1567                                     response.code, state.getInstallArgs().getUser());
1568                             try {
1569                                 ret = args.copyApk(mContainerService, true);
1570                             } catch (RemoteException e) {
1571                                 Slog.e(TAG, "Could not contact the ContainerService");
1572                             }
1573                         } else {
1574                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1575                         }
1576
1577                         Trace.asyncTraceEnd(
1578                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1579
1580                         processPendingInstall(args, ret);
1581                         mHandler.sendEmptyMessage(MCS_UNBIND);
1582                     }
1583
1584                     break;
1585                 }
1586                 case START_INTENT_FILTER_VERIFICATIONS: {
1587                     IFVerificationParams params = (IFVerificationParams) msg.obj;
1588                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1589                             params.replacing, params.pkg);
1590                     break;
1591                 }
1592                 case INTENT_FILTER_VERIFIED: {
1593                     final int verificationId = msg.arg1;
1594
1595                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1596                             verificationId);
1597                     if (state == null) {
1598                         Slog.w(TAG, "Invalid IntentFilter verification token "
1599                                 + verificationId + " received");
1600                         break;
1601                     }
1602
1603                     final int userId = state.getUserId();
1604
1605                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1606                             "Processing IntentFilter verification with token:"
1607                             + verificationId + " and userId:" + userId);
1608
1609                     final IntentFilterVerificationResponse response =
1610                             (IntentFilterVerificationResponse) msg.obj;
1611
1612                     state.setVerifierResponse(response.callerUid, response.code);
1613
1614                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1615                             "IntentFilter verification with token:" + verificationId
1616                             + " and userId:" + userId
1617                             + " is settings verifier response with response code:"
1618                             + response.code);
1619
1620                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1621                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1622                                 + response.getFailedDomainsString());
1623                     }
1624
1625                     if (state.isVerificationComplete()) {
1626                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1627                     } else {
1628                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1629                                 "IntentFilter verification with token:" + verificationId
1630                                 + " was not said to be complete");
1631                     }
1632
1633                     break;
1634                 }
1635             }
1636         }
1637     }
1638
1639     private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1640             boolean killApp, String[] grantedPermissions,
1641             boolean launchedForRestore, String installerPackage,
1642             IPackageInstallObserver2 installObserver) {
1643         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1644             // Send the removed broadcasts
1645             if (res.removedInfo != null) {
1646                 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1647             }
1648
1649             // Now that we successfully installed the package, grant runtime
1650             // permissions if requested before broadcasting the install. Also
1651             // for legacy apps in permission review mode we clear the permission
1652             // review flag which is used to emulate runtime permissions for
1653             // legacy apps.
1654             if (grantPermissions) {
1655                 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1656             }
1657
1658             final boolean update = res.removedInfo != null
1659                     && res.removedInfo.removedPackage != null;
1660
1661             // If this is the first time we have child packages for a disabled privileged
1662             // app that had no children, we grant requested runtime permissions to the new
1663             // children if the parent on the system image had them already granted.
1664             if (res.pkg.parentPackage != null) {
1665                 synchronized (mPackages) {
1666                     grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1667                 }
1668             }
1669
1670             synchronized (mPackages) {
1671                 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
1672             }
1673
1674             final String packageName = res.pkg.applicationInfo.packageName;
1675             Bundle extras = new Bundle(1);
1676             extras.putInt(Intent.EXTRA_UID, res.uid);
1677
1678             // Determine the set of users who are adding this package for
1679             // the first time vs. those who are seeing an update.
1680             int[] firstUsers = EMPTY_INT_ARRAY;
1681             int[] updateUsers = EMPTY_INT_ARRAY;
1682             if (res.origUsers == null || res.origUsers.length == 0) {
1683                 firstUsers = res.newUsers;
1684             } else {
1685                 for (int newUser : res.newUsers) {
1686                     boolean isNew = true;
1687                     for (int origUser : res.origUsers) {
1688                         if (origUser == newUser) {
1689                             isNew = false;
1690                             break;
1691                         }
1692                     }
1693                     if (isNew) {
1694                         firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1695                     } else {
1696                         updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1697                     }
1698                 }
1699             }
1700
1701             // Send installed broadcasts if the install/update is not ephemeral
1702             if (!isEphemeral(res.pkg)) {
1703                 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1704
1705                 // Send added for users that see the package for the first time
1706                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1707                         extras, 0 /*flags*/, null /*targetPackage*/,
1708                         null /*finishedReceiver*/, firstUsers);
1709
1710                 // Send added for users that don't see the package for the first time
1711                 if (update) {
1712                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
1713                 }
1714                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1715                         extras, 0 /*flags*/, null /*targetPackage*/,
1716                         null /*finishedReceiver*/, updateUsers);
1717
1718                 // Send replaced for users that don't see the package for the first time
1719                 if (update) {
1720                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1721                             packageName, extras, 0 /*flags*/,
1722                             null /*targetPackage*/, null /*finishedReceiver*/,
1723                             updateUsers);
1724                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1725                             null /*package*/, null /*extras*/, 0 /*flags*/,
1726                             packageName /*targetPackage*/,
1727                             null /*finishedReceiver*/, updateUsers);
1728                 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1729                     // First-install and we did a restore, so we're responsible for the
1730                     // first-launch broadcast.
1731                     if (DEBUG_BACKUP) {
1732                         Slog.i(TAG, "Post-restore of " + packageName
1733                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1734                     }
1735                     sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1736                 }
1737
1738                 // Send broadcast package appeared if forward locked/external for all users
1739                 // treat asec-hosted packages like removable media on upgrade
1740                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1741                     if (DEBUG_INSTALL) {
1742                         Slog.i(TAG, "upgrading pkg " + res.pkg
1743                                 + " is ASEC-hosted -> AVAILABLE");
1744                     }
1745                     final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1746                     ArrayList<String> pkgList = new ArrayList<>(1);
1747                     pkgList.add(packageName);
1748                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1749                 }
1750             }
1751
1752             // Work that needs to happen on first install within each user
1753             if (firstUsers != null && firstUsers.length > 0) {
1754                 synchronized (mPackages) {
1755                     for (int userId : firstUsers) {
1756                         // If this app is a browser and it's newly-installed for some
1757                         // users, clear any default-browser state in those users. The
1758                         // app's nature doesn't depend on the user, so we can just check
1759                         // its browser nature in any user and generalize.
1760                         if (packageIsBrowser(packageName, userId)) {
1761                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1762                         }
1763
1764                         // We may also need to apply pending (restored) runtime
1765                         // permission grants within these users.
1766                         mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1767                     }
1768                 }
1769             }
1770
1771             // Log current value of "unknown sources" setting
1772             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1773                     getUnknownSourcesSettings());
1774
1775             // Force a gc to clear up things
1776             Runtime.getRuntime().gc();
1777
1778             // Remove the replaced package's older resources safely now
1779             // We delete after a gc for applications  on sdcard.
1780             if (res.removedInfo != null && res.removedInfo.args != null) {
1781                 synchronized (mInstallLock) {
1782                     res.removedInfo.args.doPostDeleteLI(true);
1783                 }
1784             }
1785         }
1786
1787         // If someone is watching installs - notify them
1788         if (installObserver != null) {
1789             try {
1790                 Bundle extras = extrasForInstallResult(res);
1791                 installObserver.onPackageInstalled(res.name, res.returnCode,
1792                         res.returnMsg, extras);
1793             } catch (RemoteException e) {
1794                 Slog.i(TAG, "Observer no longer exists.");
1795             }
1796         }
1797     }
1798
1799     private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1800             PackageParser.Package pkg) {
1801         if (pkg.parentPackage == null) {
1802             return;
1803         }
1804         if (pkg.requestedPermissions == null) {
1805             return;
1806         }
1807         final PackageSetting disabledSysParentPs = mSettings
1808                 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1809         if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1810                 || !disabledSysParentPs.isPrivileged()
1811                 || (disabledSysParentPs.childPackageNames != null
1812                         && !disabledSysParentPs.childPackageNames.isEmpty())) {
1813             return;
1814         }
1815         final int[] allUserIds = sUserManager.getUserIds();
1816         final int permCount = pkg.requestedPermissions.size();
1817         for (int i = 0; i < permCount; i++) {
1818             String permission = pkg.requestedPermissions.get(i);
1819             BasePermission bp = mSettings.mPermissions.get(permission);
1820             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1821                 continue;
1822             }
1823             for (int userId : allUserIds) {
1824                 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1825                         permission, userId)) {
1826                     grantRuntimePermission(pkg.packageName, permission, userId);
1827                 }
1828             }
1829         }
1830     }
1831
1832     private StorageEventListener mStorageListener = new StorageEventListener() {
1833         @Override
1834         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1835             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1836                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1837                     final String volumeUuid = vol.getFsUuid();
1838
1839                     // Clean up any users or apps that were removed or recreated
1840                     // while this volume was missing
1841                     reconcileUsers(volumeUuid);
1842                     reconcileApps(volumeUuid);
1843
1844                     // Clean up any install sessions that expired or were
1845                     // cancelled while this volume was missing
1846                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
1847
1848                     loadPrivatePackages(vol);
1849
1850                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1851                     unloadPrivatePackages(vol);
1852                 }
1853             }
1854
1855             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1856                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1857                     updateExternalMediaStatus(true, false);
1858                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1859                     updateExternalMediaStatus(false, false);
1860                 }
1861             }
1862         }
1863
1864         @Override
1865         public void onVolumeForgotten(String fsUuid) {
1866             if (TextUtils.isEmpty(fsUuid)) {
1867                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1868                 return;
1869             }
1870
1871             // Remove any apps installed on the forgotten volume
1872             synchronized (mPackages) {
1873                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1874                 for (PackageSetting ps : packages) {
1875                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1876                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1877                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1878                 }
1879
1880                 mSettings.onVolumeForgotten(fsUuid);
1881                 mSettings.writeLPr();
1882             }
1883         }
1884     };
1885
1886     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1887             String[] grantedPermissions) {
1888         for (int userId : userIds) {
1889             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1890         }
1891     }
1892
1893     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1894             String[] grantedPermissions) {
1895         SettingBase sb = (SettingBase) pkg.mExtras;
1896         if (sb == null) {
1897             return;
1898         }
1899
1900         PermissionsState permissionsState = sb.getPermissionsState();
1901
1902         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1903                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1904
1905         final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1906                 >= Build.VERSION_CODES.M;
1907
1908         for (String permission : pkg.requestedPermissions) {
1909             final BasePermission bp;
1910             synchronized (mPackages) {
1911                 bp = mSettings.mPermissions.get(permission);
1912             }
1913             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1914                     && (grantedPermissions == null
1915                            || ArrayUtils.contains(grantedPermissions, permission))) {
1916                 final int flags = permissionsState.getPermissionFlags(permission, userId);
1917                 if (supportsRuntimePermissions) {
1918                     // Installer cannot change immutable permissions.
1919                     if ((flags & immutableFlags) == 0) {
1920                         grantRuntimePermission(pkg.packageName, permission, userId);
1921                     }
1922                 } else if (mPermissionReviewRequired) {
1923                     // In permission review mode we clear the review flag when we
1924                     // are asked to install the app with all permissions granted.
1925                     if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1926                         updatePermissionFlags(permission, pkg.packageName,
1927                                 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0 /*value*/, userId);
1928                     }
1929                 }
1930             }
1931         }
1932     }
1933
1934     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1935         Bundle extras = null;
1936         switch (res.returnCode) {
1937             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1938                 extras = new Bundle();
1939                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1940                         res.origPermission);
1941                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1942                         res.origPackage);
1943                 break;
1944             }
1945             case PackageManager.INSTALL_SUCCEEDED: {
1946                 extras = new Bundle();
1947                 extras.putBoolean(Intent.EXTRA_REPLACING,
1948                         res.removedInfo != null && res.removedInfo.removedPackage != null);
1949                 break;
1950             }
1951         }
1952         return extras;
1953     }
1954
1955     void scheduleWriteSettingsLocked() {
1956         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1957             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1958         }
1959     }
1960
1961     void scheduleWritePackageListLocked(int userId) {
1962         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
1963             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
1964             msg.arg1 = userId;
1965             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
1966         }
1967     }
1968
1969     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
1970         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
1971         scheduleWritePackageRestrictionsLocked(userId);
1972     }
1973
1974     void scheduleWritePackageRestrictionsLocked(int userId) {
1975         final int[] userIds = (userId == UserHandle.USER_ALL)
1976                 ? sUserManager.getUserIds() : new int[]{userId};
1977         for (int nextUserId : userIds) {
1978             if (!sUserManager.exists(nextUserId)) return;
1979             mDirtyUsers.add(nextUserId);
1980             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1981                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1982             }
1983         }
1984     }
1985
1986     public static PackageManagerService main(Context context, Installer installer,
1987             boolean factoryTest, boolean onlyCore) {
1988         // Self-check for initial settings.
1989         PackageManagerServiceCompilerMapping.checkProperties();
1990
1991         PackageManagerService m = new PackageManagerService(context, installer,
1992                 factoryTest, onlyCore);
1993         m.enableSystemUserPackages();
1994         ServiceManager.addService("package", m);
1995         return m;
1996     }
1997
1998     private void enableSystemUserPackages() {
1999         if (!UserManager.isSplitSystemUser()) {
2000             return;
2001         }
2002         // For system user, enable apps based on the following conditions:
2003         // - app is whitelisted or belong to one of these groups:
2004         //   -- system app which has no launcher icons
2005         //   -- system app which has INTERACT_ACROSS_USERS permission
2006         //   -- system IME app
2007         // - app is not in the blacklist
2008         AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2009         Set<String> enableApps = new ArraySet<>();
2010         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2011                 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2012                 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2013         ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2014         enableApps.addAll(wlApps);
2015         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2016                 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2017         ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2018         enableApps.removeAll(blApps);
2019         Log.i(TAG, "Applications installed for system user: " + enableApps);
2020         List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2021                 UserHandle.SYSTEM);
2022         final int allAppsSize = allAps.size();
2023         synchronized (mPackages) {
2024             for (int i = 0; i < allAppsSize; i++) {
2025                 String pName = allAps.get(i);
2026                 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2027                 // Should not happen, but we shouldn't be failing if it does
2028                 if (pkgSetting == null) {
2029                     continue;
2030                 }
2031                 boolean install = enableApps.contains(pName);
2032                 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2033                     Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2034                             + " for system user");
2035                     pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2036                 }
2037             }
2038         }
2039     }
2040
2041     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2042         DisplayManager displayManager = (DisplayManager) context.getSystemService(
2043                 Context.DISPLAY_SERVICE);
2044         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2045     }
2046
2047     /**
2048      * Requests that files preopted on a secondary system partition be copied to the data partition
2049      * if possible.  Note that the actual copying of the files is accomplished by init for security
2050      * reasons. This simply requests that the copy takes place and awaits confirmation of its
2051      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2052      */
2053     private static void requestCopyPreoptedFiles() {
2054         final int WAIT_TIME_MS = 100;
2055         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2056         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2057             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2058             // We will wait for up to 100 seconds.
2059             final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000;
2060             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2061                 try {
2062                     Thread.sleep(WAIT_TIME_MS);
2063                 } catch (InterruptedException e) {
2064                     // Do nothing
2065                 }
2066                 if (SystemClock.uptimeMillis() > timeEnd) {
2067                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2068                     Slog.wtf(TAG, "cppreopt did not finish!");
2069                     break;
2070                 }
2071             }
2072         }
2073     }
2074
2075     public PackageManagerService(Context context, Installer installer,
2076             boolean factoryTest, boolean onlyCore) {
2077         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2078                 SystemClock.uptimeMillis());
2079
2080         if (mSdkVersion <= 0) {
2081             Slog.w(TAG, "**** ro.build.version.sdk not set!");
2082         }
2083
2084         mContext = context;
2085
2086         mPermissionReviewRequired = context.getResources().getBoolean(
2087                 R.bool.config_permissionReviewRequired);
2088
2089         mFactoryTest = factoryTest;
2090         mOnlyCore = onlyCore;
2091         mMetrics = new DisplayMetrics();
2092         mSettings = new Settings(mPackages);
2093         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2094                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2095         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2096                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2097         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2098                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2099         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2100                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2101         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2102                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2103         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2104                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2105
2106         String separateProcesses = SystemProperties.get("debug.separate_processes");
2107         if (separateProcesses != null && separateProcesses.length() > 0) {
2108             if ("*".equals(separateProcesses)) {
2109                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2110                 mSeparateProcesses = null;
2111                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2112             } else {
2113                 mDefParseFlags = 0;
2114                 mSeparateProcesses = separateProcesses.split(",");
2115                 Slog.w(TAG, "Running with debug.separate_processes: "
2116                         + separateProcesses);
2117             }
2118         } else {
2119             mDefParseFlags = 0;
2120             mSeparateProcesses = null;
2121         }
2122
2123         mInstaller = installer;
2124         mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2125                 "*dexopt*");
2126         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2127
2128         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2129                 FgThread.get().getLooper());
2130
2131         getDefaultDisplayMetrics(context, mMetrics);
2132
2133         SystemConfig systemConfig = SystemConfig.getInstance();
2134         mGlobalGids = systemConfig.getGlobalGids();
2135         mSystemPermissions = systemConfig.getSystemPermissions();
2136         mAvailableFeatures = systemConfig.getAvailableFeatures();
2137
2138         mProtectedPackages = new ProtectedPackages(mContext);
2139
2140         synchronized (mInstallLock) {
2141         // writer
2142         synchronized (mPackages) {
2143             mHandlerThread = new ServiceThread(TAG,
2144                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2145             mHandlerThread.start();
2146             mHandler = new PackageHandler(mHandlerThread.getLooper());
2147             mProcessLoggingHandler = new ProcessLoggingHandler();
2148             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2149
2150             mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2151
2152             File dataDir = Environment.getDataDirectory();
2153             mAppInstallDir = new File(dataDir, "app");
2154             mAppLib32InstallDir = new File(dataDir, "app-lib");
2155             mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
2156             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2157             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2158
2159             sUserManager = new UserManagerService(context, this, mPackages);
2160
2161             // Propagate permission configuration in to package manager.
2162             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2163                     = systemConfig.getPermissions();
2164             for (int i=0; i<permConfig.size(); i++) {
2165                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2166                 BasePermission bp = mSettings.mPermissions.get(perm.name);
2167                 if (bp == null) {
2168                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2169                     mSettings.mPermissions.put(perm.name, bp);
2170                 }
2171                 if (perm.gids != null) {
2172                     bp.setGids(perm.gids, perm.perUser);
2173                 }
2174             }
2175
2176             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2177             for (int i=0; i<libConfig.size(); i++) {
2178                 mSharedLibraries.put(libConfig.keyAt(i),
2179                         new SharedLibraryEntry(libConfig.valueAt(i), null));
2180             }
2181
2182             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2183
2184             mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2185
2186             // Clean up orphaned packages for which the code path doesn't exist
2187             // and they are an update to a system app - caused by bug/32321269
2188             final int packageSettingCount = mSettings.mPackages.size();
2189             for (int i = packageSettingCount - 1; i >= 0; i--) {
2190                 PackageSetting ps = mSettings.mPackages.valueAt(i);
2191                 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2192                         && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2193                     mSettings.mPackages.removeAt(i);
2194                     mSettings.enableSystemPackageLPw(ps.name);
2195                 }
2196             }
2197
2198             if (mFirstBoot) {
2199                 requestCopyPreoptedFiles();
2200             }
2201
2202             String customResolverActivity = Resources.getSystem().getString(
2203                     R.string.config_customResolverActivity);
2204             if (TextUtils.isEmpty(customResolverActivity)) {
2205                 customResolverActivity = null;
2206             } else {
2207                 mCustomResolverComponentName = ComponentName.unflattenFromString(
2208                         customResolverActivity);
2209             }
2210
2211             long startTime = SystemClock.uptimeMillis();
2212
2213             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2214                     startTime);
2215
2216             // Set flag to monitor and not change apk file paths when
2217             // scanning install directories.
2218             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
2219
2220             final String bootClassPath = System.getenv("BOOTCLASSPATH");
2221             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2222
2223             if (bootClassPath == null) {
2224                 Slog.w(TAG, "No BOOTCLASSPATH found!");
2225             }
2226
2227             if (systemServerClassPath == null) {
2228                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2229             }
2230
2231             final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2232             final String[] dexCodeInstructionSets =
2233                     getDexCodeInstructionSets(
2234                             allInstructionSets.toArray(new String[allInstructionSets.size()]));
2235
2236             /**
2237              * Ensure all external libraries have had dexopt run on them.
2238              */
2239             if (mSharedLibraries.size() > 0) {
2240                 // NOTE: For now, we're compiling these system "shared libraries"
2241                 // (and framework jars) into all available architectures. It's possible
2242                 // to compile them only when we come across an app that uses them (there's
2243                 // already logic for that in scanPackageLI) but that adds some complexity.
2244                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2245                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
2246                         final String lib = libEntry.path;
2247                         if (lib == null) {
2248                             continue;
2249                         }
2250
2251                         try {
2252                             // Shared libraries do not have profiles so we perform a full
2253                             // AOT compilation (if needed).
2254                             int dexoptNeeded = DexFile.getDexOptNeeded(
2255                                     lib, dexCodeInstructionSet,
2256                                     getCompilerFilterForReason(REASON_SHARED_APK),
2257                                     false /* newProfile */);
2258                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2259                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
2260                                         dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
2261                                         getCompilerFilterForReason(REASON_SHARED_APK),
2262                                         StorageManager.UUID_PRIVATE_INTERNAL,
2263                                         SKIP_SHARED_LIBRARY_CHECK);
2264                             }
2265                         } catch (FileNotFoundException e) {
2266                             Slog.w(TAG, "Library not found: " + lib);
2267                         } catch (IOException | InstallerException e) {
2268                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
2269                                     + e.getMessage());
2270                         }
2271                     }
2272                 }
2273             }
2274
2275             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2276
2277             final VersionInfo ver = mSettings.getInternalVersion();
2278             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2279
2280             // when upgrading from pre-M, promote system app permissions from install to runtime
2281             mPromoteSystemApps =
2282                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2283
2284             // When upgrading from pre-N, we need to handle package extraction like first boot,
2285             // as there is no profiling data available.
2286             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2287
2288             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2289
2290             // save off the names of pre-existing system packages prior to scanning; we don't
2291             // want to automatically grant runtime permissions for new system apps
2292             if (mPromoteSystemApps) {
2293                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2294                 while (pkgSettingIter.hasNext()) {
2295                     PackageSetting ps = pkgSettingIter.next();
2296                     if (isSystemApp(ps)) {
2297                         mExistingSystemPackages.add(ps.name);
2298                     }
2299                 }
2300             }
2301
2302             // Collect vendor overlay packages. (Do this before scanning any apps.)
2303             // For security and version matching reason, only consider
2304             // overlay packages if they reside in the right directory.
2305             String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY);
2306             if (!overlayThemeDir.isEmpty()) {
2307                 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags
2308                         | PackageParser.PARSE_IS_SYSTEM
2309                         | PackageParser.PARSE_IS_SYSTEM_DIR
2310                         | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2311             }
2312             scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2313                     | PackageParser.PARSE_IS_SYSTEM
2314                     | PackageParser.PARSE_IS_SYSTEM_DIR
2315                     | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2316
2317             // Find base frameworks (resource packages without code).
2318             scanDirTracedLI(frameworkDir, mDefParseFlags
2319                     | PackageParser.PARSE_IS_SYSTEM
2320                     | PackageParser.PARSE_IS_SYSTEM_DIR
2321                     | PackageParser.PARSE_IS_PRIVILEGED,
2322                     scanFlags | SCAN_NO_DEX, 0);
2323
2324             // Collected privileged system packages.
2325             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2326             scanDirTracedLI(privilegedAppDir, mDefParseFlags
2327                     | PackageParser.PARSE_IS_SYSTEM
2328                     | PackageParser.PARSE_IS_SYSTEM_DIR
2329                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2330
2331             // Collect ordinary system packages.
2332             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2333             scanDirTracedLI(systemAppDir, mDefParseFlags
2334                     | PackageParser.PARSE_IS_SYSTEM
2335                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2336
2337             // Collect all vendor packages.
2338             File vendorAppDir = new File("/vendor/app");
2339             try {
2340                 vendorAppDir = vendorAppDir.getCanonicalFile();
2341             } catch (IOException e) {
2342                 // failed to look up canonical path, continue with original one
2343             }
2344             scanDirTracedLI(vendorAppDir, mDefParseFlags
2345                     | PackageParser.PARSE_IS_SYSTEM
2346                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2347
2348             // Collect all OEM packages.
2349             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2350             scanDirTracedLI(oemAppDir, mDefParseFlags
2351                     | PackageParser.PARSE_IS_SYSTEM
2352                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2353
2354             // Prune any system packages that no longer exist.
2355             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2356             if (!mOnlyCore) {
2357                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2358                 while (psit.hasNext()) {
2359                     PackageSetting ps = psit.next();
2360
2361                     /*
2362                      * If this is not a system app, it can't be a
2363                      * disable system app.
2364                      */
2365                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2366                         continue;
2367                     }
2368
2369                     /*
2370                      * If the package is scanned, it's not erased.
2371                      */
2372                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2373                     if (scannedPkg != null) {
2374                         /*
2375                          * If the system app is both scanned and in the
2376                          * disabled packages list, then it must have been
2377                          * added via OTA. Remove it from the currently
2378                          * scanned package so the previously user-installed
2379                          * application can be scanned.
2380                          */
2381                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2382                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2383                                     + ps.name + "; removing system app.  Last known codePath="
2384                                     + ps.codePathString + ", installStatus=" + ps.installStatus
2385                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2386                                     + scannedPkg.mVersionCode);
2387                             removePackageLI(scannedPkg, true);
2388                             mExpectingBetter.put(ps.name, ps.codePath);
2389                         }
2390
2391                         continue;
2392                     }
2393
2394                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2395                         psit.remove();
2396                         logCriticalInfo(Log.WARN, "System package " + ps.name
2397                                 + " no longer exists; it's data will be wiped");
2398                         // Actual deletion of code and data will be handled by later
2399                         // reconciliation step
2400                     } else {
2401                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2402                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2403                             possiblyDeletedUpdatedSystemApps.add(ps.name);
2404                         }
2405                     }
2406                 }
2407             }
2408
2409             //look for any incomplete package installations
2410             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2411             for (int i = 0; i < deletePkgsList.size(); i++) {
2412                 // Actual deletion of code and data will be handled by later
2413                 // reconciliation step
2414                 final String packageName = deletePkgsList.get(i).name;
2415                 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2416                 synchronized (mPackages) {
2417                     mSettings.removePackageLPw(packageName);
2418                 }
2419             }
2420
2421             //delete tmp files
2422             deleteTempPackageFiles();
2423
2424             // Remove any shared userIDs that have no associated packages
2425             mSettings.pruneSharedUsersLPw();
2426
2427             if (!mOnlyCore) {
2428                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2429                         SystemClock.uptimeMillis());
2430                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2431
2432                 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2433                         | PackageParser.PARSE_FORWARD_LOCK,
2434                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2435
2436                 scanDirLI(mEphemeralInstallDir, mDefParseFlags
2437                         | PackageParser.PARSE_IS_EPHEMERAL,
2438                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2439
2440                 /**
2441                  * Remove disable package settings for any updated system
2442                  * apps that were removed via an OTA. If they're not a
2443                  * previously-updated app, remove them completely.
2444                  * Otherwise, just revoke their system-level permissions.
2445                  */
2446                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2447                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2448                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2449
2450                     String msg;
2451                     if (deletedPkg == null) {
2452                         msg = "Updated system package " + deletedAppName
2453                                 + " no longer exists; it's data will be wiped";
2454                         // Actual deletion of code and data will be handled by later
2455                         // reconciliation step
2456                     } else {
2457                         msg = "Updated system app + " + deletedAppName
2458                                 + " no longer present; removing system privileges for "
2459                                 + deletedAppName;
2460
2461                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2462
2463                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2464                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2465                     }
2466                     logCriticalInfo(Log.WARN, msg);
2467                 }
2468
2469                 /**
2470                  * Make sure all system apps that we expected to appear on
2471                  * the userdata partition actually showed up. If they never
2472                  * appeared, crawl back and revive the system version.
2473                  */
2474                 for (int i = 0; i < mExpectingBetter.size(); i++) {
2475                     final String packageName = mExpectingBetter.keyAt(i);
2476                     if (!mPackages.containsKey(packageName)) {
2477                         final File scanFile = mExpectingBetter.valueAt(i);
2478
2479                         logCriticalInfo(Log.WARN, "Expected better " + packageName
2480                                 + " but never showed up; reverting to system");
2481
2482                         int reparseFlags = mDefParseFlags;
2483                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
2484                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2485                                     | PackageParser.PARSE_IS_SYSTEM_DIR
2486                                     | PackageParser.PARSE_IS_PRIVILEGED;
2487                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
2488                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2489                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2490                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2491                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2492                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2493                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
2494                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2495                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2496                         } else {
2497                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2498                             continue;
2499                         }
2500
2501                         mSettings.enableSystemPackageLPw(packageName);
2502
2503                         try {
2504                             scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2505                         } catch (PackageManagerException e) {
2506                             Slog.e(TAG, "Failed to parse original system package: "
2507                                     + e.getMessage());
2508                         }
2509                     }
2510                 }
2511             }
2512             mExpectingBetter.clear();
2513
2514             // Resolve the storage manager.
2515             mStorageManagerPackage = getStorageManagerPackageName();
2516
2517             // Resolve protected action filters. Only the setup wizard is allowed to
2518             // have a high priority filter for these actions.
2519             mSetupWizardPackage = getSetupWizardPackageName();
2520             if (mProtectedFilters.size() > 0) {
2521                 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2522                     Slog.i(TAG, "No setup wizard;"
2523                         + " All protected intents capped to priority 0");
2524                 }
2525                 for (ActivityIntentInfo filter : mProtectedFilters) {
2526                     if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2527                         if (DEBUG_FILTERS) {
2528                             Slog.i(TAG, "Found setup wizard;"
2529                                 + " allow priority " + filter.getPriority() + ";"
2530                                 + " package: " + filter.activity.info.packageName
2531                                 + " activity: " + filter.activity.className
2532                                 + " priority: " + filter.getPriority());
2533                         }
2534                         // skip setup wizard; allow it to keep the high priority filter
2535                         continue;
2536                     }
2537                     Slog.w(TAG, "Protected action; cap priority to 0;"
2538                             + " package: " + filter.activity.info.packageName
2539                             + " activity: " + filter.activity.className
2540                             + " origPrio: " + filter.getPriority());
2541                     filter.setPriority(0);
2542                 }
2543             }
2544             mDeferProtectedFilters = false;
2545             mProtectedFilters.clear();
2546
2547             // Now that we know all of the shared libraries, update all clients to have
2548             // the correct library paths.
2549             updateAllSharedLibrariesLPw();
2550
2551             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2552                 // NOTE: We ignore potential failures here during a system scan (like
2553                 // the rest of the commands above) because there's precious little we
2554                 // can do about it. A settings error is reported, though.
2555                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2556                         false /* boot complete */);
2557             }
2558
2559             // Now that we know all the packages we are keeping,
2560             // read and update their last usage times.
2561             mPackageUsage.read(mPackages);
2562             mCompilerStats.read();
2563
2564             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2565                     SystemClock.uptimeMillis());
2566             Slog.i(TAG, "Time to scan packages: "
2567                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
2568                     + " seconds");
2569
2570             // If the platform SDK has changed since the last time we booted,
2571             // we need to re-grant app permission to catch any new ones that
2572             // appear.  This is really a hack, and means that apps can in some
2573             // cases get permissions that the user didn't initially explicitly
2574             // allow...  it would be nice to have some better way to handle
2575             // this situation.
2576             int updateFlags = UPDATE_PERMISSIONS_ALL;
2577             if (ver.sdkVersion != mSdkVersion) {
2578                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2579                         + mSdkVersion + "; regranting permissions for internal storage");
2580                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2581             }
2582             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2583             ver.sdkVersion = mSdkVersion;
2584
2585             // If this is the first boot or an update from pre-M, and it is a normal
2586             // boot, then we need to initialize the default preferred apps across
2587             // all defined users.
2588             if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2589                 for (UserInfo user : sUserManager.getUsers(true)) {
2590                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2591                     applyFactoryDefaultBrowserLPw(user.id);
2592                     primeDomainVerificationsLPw(user.id);
2593                 }
2594             }
2595
2596             // Prepare storage for system user really early during boot,
2597             // since core system apps like SettingsProvider and SystemUI
2598             // can't wait for user to start
2599             final int storageFlags;
2600             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2601                 storageFlags = StorageManager.FLAG_STORAGE_DE;
2602             } else {
2603                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2604             }
2605             reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
2606                     storageFlags);
2607
2608             // If this is first boot after an OTA, and a normal boot, then
2609             // we need to clear code cache directories.
2610             // Note that we do *not* clear the application profiles. These remain valid
2611             // across OTAs and are used to drive profile verification (post OTA) and
2612             // profile compilation (without waiting to collect a fresh set of profiles).
2613             if (mIsUpgrade && !onlyCore) {
2614                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2615                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2616                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
2617                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2618                         // No apps are running this early, so no need to freeze
2619                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2620                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2621                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2622                     }
2623                 }
2624                 ver.fingerprint = Build.FINGERPRINT;
2625             }
2626
2627             checkDefaultBrowser();
2628
2629             // clear only after permissions and other defaults have been updated
2630             mExistingSystemPackages.clear();
2631             mPromoteSystemApps = false;
2632
2633             // All the changes are done during package scanning.
2634             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2635
2636             // can downgrade to reader
2637             mSettings.writeLPr();
2638
2639             // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
2640             // early on (before the package manager declares itself as early) because other
2641             // components in the system server might ask for package contexts for these apps.
2642             //
2643             // Note that "onlyCore" in this context means the system is encrypted or encrypting
2644             // (i.e, that the data partition is unavailable).
2645             if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
2646                 long start = System.nanoTime();
2647                 List<PackageParser.Package> coreApps = new ArrayList<>();
2648                 for (PackageParser.Package pkg : mPackages.values()) {
2649                     if (pkg.coreApp) {
2650                         coreApps.add(pkg);
2651                     }
2652                 }
2653
2654                 int[] stats = performDexOptUpgrade(coreApps, false,
2655                         getCompilerFilterForReason(REASON_CORE_APP));
2656
2657                 final int elapsedTimeSeconds =
2658                         (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
2659                 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
2660
2661                 if (DEBUG_DEXOPT) {
2662                     Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
2663                             stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
2664                 }
2665
2666
2667                 // TODO: Should we log these stats to tron too ?
2668                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
2669                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
2670                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
2671                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
2672             }
2673
2674             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2675                     SystemClock.uptimeMillis());
2676
2677             if (!mOnlyCore) {
2678                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2679                 mRequiredInstallerPackage = getRequiredInstallerLPr();
2680                 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2681                 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2682                 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2683                         mIntentFilterVerifierComponent);
2684                 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2685                         PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
2686                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2687                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
2688             } else {
2689                 mRequiredVerifierPackage = null;
2690                 mRequiredInstallerPackage = null;
2691                 mRequiredUninstallerPackage = null;
2692                 mIntentFilterVerifierComponent = null;
2693                 mIntentFilterVerifier = null;
2694                 mServicesSystemSharedLibraryPackageName = null;
2695                 mSharedSystemSharedLibraryPackageName = null;
2696             }
2697
2698             mInstallerService = new PackageInstallerService(context, this);
2699
2700             final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2701             final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
2702             // both the installer and resolver must be present to enable ephemeral
2703             if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
2704                 if (DEBUG_EPHEMERAL) {
2705                     Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
2706                             + " installer:" + ephemeralInstallerComponent);
2707                 }
2708                 mEphemeralResolverComponent = ephemeralResolverComponent;
2709                 mEphemeralInstallerComponent = ephemeralInstallerComponent;
2710                 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2711                 mEphemeralResolverConnection =
2712                         new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
2713             } else {
2714                 if (DEBUG_EPHEMERAL) {
2715                     final String missingComponent =
2716                             (ephemeralResolverComponent == null)
2717                             ? (ephemeralInstallerComponent == null)
2718                                     ? "resolver and installer"
2719                                     : "resolver"
2720                             : "installer";
2721                     Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
2722                 }
2723                 mEphemeralResolverComponent = null;
2724                 mEphemeralInstallerComponent = null;
2725                 mEphemeralResolverConnection = null;
2726             }
2727
2728             mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
2729         } // synchronized (mPackages)
2730         } // synchronized (mInstallLock)
2731
2732         // Now after opening every single application zip, make sure they
2733         // are all flushed.  Not really needed, but keeps things nice and
2734         // tidy.
2735         Runtime.getRuntime().gc();
2736
2737         // The initial scanning above does many calls into installd while
2738         // holding the mPackages lock, but we're mostly interested in yelling
2739         // once we have a booted system.
2740         mInstaller.setWarnIfHeld(mPackages);
2741
2742         // Expose private service for system components to use.
2743         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2744     }
2745
2746     @Override
2747     public boolean isFirstBoot() {
2748         return mFirstBoot;
2749     }
2750
2751     @Override
2752     public boolean isOnlyCoreApps() {
2753         return mOnlyCore;
2754     }
2755
2756     @Override
2757     public boolean isUpgrade() {
2758         return mIsUpgrade;
2759     }
2760
2761     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2762         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2763
2764         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2765                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2766                 UserHandle.USER_SYSTEM);
2767         if (matches.size() == 1) {
2768             return matches.get(0).getComponentInfo().packageName;
2769         } else if (matches.size() == 0) {
2770             Log.e(TAG, "There should probably be a verifier, but, none were found");
2771             return null;
2772         }
2773         throw new RuntimeException("There must be exactly one verifier; found " + matches);
2774     }
2775
2776     private @NonNull String getRequiredSharedLibraryLPr(String libraryName) {
2777         synchronized (mPackages) {
2778             SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName);
2779             if (libraryEntry == null) {
2780                 throw new IllegalStateException("Missing required shared library:" + libraryName);
2781             }
2782             return libraryEntry.apk;
2783         }
2784     }
2785
2786     private @NonNull String getRequiredInstallerLPr() {
2787         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2788         intent.addCategory(Intent.CATEGORY_DEFAULT);
2789         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2790
2791         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2792                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2793                 UserHandle.USER_SYSTEM);
2794         if (matches.size() == 1) {
2795             ResolveInfo resolveInfo = matches.get(0);
2796             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
2797                 throw new RuntimeException("The installer must be a privileged app");
2798             }
2799             return matches.get(0).getComponentInfo().packageName;
2800         } else {
2801             throw new RuntimeException("There must be exactly one installer; found " + matches);
2802         }
2803     }
2804
2805     private @NonNull String getRequiredUninstallerLPr() {
2806         final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
2807         intent.addCategory(Intent.CATEGORY_DEFAULT);
2808         intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
2809
2810         final ResolveInfo resolveInfo = resolveIntent(intent, null,
2811                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2812                 UserHandle.USER_SYSTEM);
2813         if (resolveInfo == null ||
2814                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
2815             throw new RuntimeException("There must be exactly one uninstaller; found "
2816                     + resolveInfo);
2817         }
2818         return resolveInfo.getComponentInfo().packageName;
2819     }
2820
2821     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2822         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2823
2824         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2825                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2826                 UserHandle.USER_SYSTEM);
2827         ResolveInfo best = null;
2828         final int N = matches.size();
2829         for (int i = 0; i < N; i++) {
2830             final ResolveInfo cur = matches.get(i);
2831             final String packageName = cur.getComponentInfo().packageName;
2832             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2833                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2834                 continue;
2835             }
2836
2837             if (best == null || cur.priority > best.priority) {
2838                 best = cur;
2839             }
2840         }
2841
2842         if (best != null) {
2843             return best.getComponentInfo().getComponentName();
2844         } else {
2845             throw new RuntimeException("There must be at least one intent filter verifier");
2846         }
2847     }
2848
2849     private @Nullable ComponentName getEphemeralResolverLPr() {
2850         final String[] packageArray =
2851                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2852         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
2853             if (DEBUG_EPHEMERAL) {
2854                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2855             }
2856             return null;
2857         }
2858
2859         final int resolveFlags =
2860                 MATCH_DIRECT_BOOT_AWARE
2861                 | MATCH_DIRECT_BOOT_UNAWARE
2862                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2863         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2864         final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
2865                 resolveFlags, UserHandle.USER_SYSTEM);
2866
2867         final int N = resolvers.size();
2868         if (N == 0) {
2869             if (DEBUG_EPHEMERAL) {
2870                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2871             }
2872             return null;
2873         }
2874
2875         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2876         for (int i = 0; i < N; i++) {
2877             final ResolveInfo info = resolvers.get(i);
2878
2879             if (info.serviceInfo == null) {
2880                 continue;
2881             }
2882
2883             final String packageName = info.serviceInfo.packageName;
2884             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
2885                 if (DEBUG_EPHEMERAL) {
2886                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2887                             + " pkg: " + packageName + ", info:" + info);
2888                 }
2889                 continue;
2890             }
2891
2892             if (DEBUG_EPHEMERAL) {
2893                 Slog.v(TAG, "Ephemeral resolver found;"
2894                         + " pkg: " + packageName + ", info:" + info);
2895             }
2896             return new ComponentName(packageName, info.serviceInfo.name);
2897         }
2898         if (DEBUG_EPHEMERAL) {
2899             Slog.v(TAG, "Ephemeral resolver NOT found");
2900         }
2901         return null;
2902     }
2903
2904     private @Nullable ComponentName getEphemeralInstallerLPr() {
2905         final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2906         intent.addCategory(Intent.CATEGORY_DEFAULT);
2907         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2908
2909         final int resolveFlags =
2910                 MATCH_DIRECT_BOOT_AWARE
2911                 | MATCH_DIRECT_BOOT_UNAWARE
2912                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2913         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2914                 resolveFlags, UserHandle.USER_SYSTEM);
2915         if (matches.size() == 0) {
2916             return null;
2917         } else if (matches.size() == 1) {
2918             return matches.get(0).getComponentInfo().getComponentName();
2919         } else {
2920             throw new RuntimeException(
2921                     "There must be at most one ephemeral installer; found " + matches);
2922         }
2923     }
2924
2925     private void primeDomainVerificationsLPw(int userId) {
2926         if (DEBUG_DOMAIN_VERIFICATION) {
2927             Slog.d(TAG, "Priming domain verifications in user " + userId);
2928         }
2929
2930         SystemConfig systemConfig = SystemConfig.getInstance();
2931         ArraySet<String> packages = systemConfig.getLinkedApps();
2932         ArraySet<String> domains = new ArraySet<String>();
2933
2934         for (String packageName : packages) {
2935             PackageParser.Package pkg = mPackages.get(packageName);
2936             if (pkg != null) {
2937                 if (!pkg.isSystemApp()) {
2938                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2939                     continue;
2940                 }
2941
2942                 domains.clear();
2943                 for (PackageParser.Activity a : pkg.activities) {
2944                     for (ActivityIntentInfo filter : a.intents) {
2945                         if (hasValidDomains(filter)) {
2946                             domains.addAll(filter.getHostsList());
2947                         }
2948                     }
2949                 }
2950
2951                 if (domains.size() > 0) {
2952                     if (DEBUG_DOMAIN_VERIFICATION) {
2953                         Slog.v(TAG, "      + " + packageName);
2954                     }
2955                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2956                     // state w.r.t. the formal app-linkage "no verification attempted" state;
2957                     // and then 'always' in the per-user state actually used for intent resolution.
2958                     final IntentFilterVerificationInfo ivi;
2959                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2960                             new ArrayList<String>(domains));
2961                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2962                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2963                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2964                 } else {
2965                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2966                             + "' does not handle web links");
2967                 }
2968             } else {
2969                 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2970             }
2971         }
2972
2973         scheduleWritePackageRestrictionsLocked(userId);
2974         scheduleWriteSettingsLocked();
2975     }
2976
2977     private void applyFactoryDefaultBrowserLPw(int userId) {
2978         // The default browser app's package name is stored in a string resource,
2979         // with a product-specific overlay used for vendor customization.
2980         String browserPkg = mContext.getResources().getString(
2981                 com.android.internal.R.string.default_browser);
2982         if (!TextUtils.isEmpty(browserPkg)) {
2983             // non-empty string => required to be a known package
2984             PackageSetting ps = mSettings.mPackages.get(browserPkg);
2985             if (ps == null) {
2986                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2987                 browserPkg = null;
2988             } else {
2989                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2990             }
2991         }
2992
2993         // Nothing valid explicitly set? Make the factory-installed browser the explicit
2994         // default.  If there's more than one, just leave everything alone.
2995         if (browserPkg == null) {
2996             calculateDefaultBrowserLPw(userId);
2997         }
2998     }
2999
3000     private void calculateDefaultBrowserLPw(int userId) {
3001         List<String> allBrowsers = resolveAllBrowserApps(userId);
3002         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3003         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3004     }
3005
3006     private List<String> resolveAllBrowserApps(int userId) {
3007         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3008         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3009                 PackageManager.MATCH_ALL, userId);
3010
3011         final int count = list.size();
3012         List<String> result = new ArrayList<String>(count);
3013         for (int i=0; i<count; i++) {
3014             ResolveInfo info = list.get(i);
3015             if (info.activityInfo == null
3016                     || !info.handleAllWebDataURI
3017                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3018                     || result.contains(info.activityInfo.packageName)) {
3019                 continue;
3020             }
3021             result.add(info.activityInfo.packageName);
3022         }
3023
3024         return result;
3025     }
3026
3027     private boolean packageIsBrowser(String packageName, int userId) {
3028         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3029                 PackageManager.MATCH_ALL, userId);
3030         final int N = list.size();
3031         for (int i = 0; i < N; i++) {
3032             ResolveInfo info = list.get(i);
3033             if (packageName.equals(info.activityInfo.packageName)) {
3034                 return true;
3035             }
3036         }
3037         return false;
3038     }
3039
3040     private void checkDefaultBrowser() {
3041         final int myUserId = UserHandle.myUserId();
3042         final String packageName = getDefaultBrowserPackageName(myUserId);
3043         if (packageName != null) {
3044             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3045             if (info == null) {
3046                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3047                 synchronized (mPackages) {
3048                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3049                 }
3050             }
3051         }
3052     }
3053
3054     @Override
3055     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3056             throws RemoteException {
3057         try {
3058             return super.onTransact(code, data, reply, flags);
3059         } catch (RuntimeException e) {
3060             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3061                 Slog.wtf(TAG, "Package Manager Crash", e);
3062             }
3063             throw e;
3064         }
3065     }
3066
3067     static int[] appendInts(int[] cur, int[] add) {
3068         if (add == null) return cur;
3069         if (cur == null) return add;
3070         final int N = add.length;
3071         for (int i=0; i<N; i++) {
3072             cur = appendInt(cur, add[i]);
3073         }
3074         return cur;
3075     }
3076
3077     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3078         if (!sUserManager.exists(userId)) return null;
3079         if (ps == null) {
3080             return null;
3081         }
3082         final PackageParser.Package p = ps.pkg;
3083         if (p == null) {
3084             return null;
3085         }
3086
3087         final PermissionsState permissionsState = ps.getPermissionsState();
3088
3089         // Compute GIDs only if requested
3090         final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3091                 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3092         // Compute granted permissions only if package has requested permissions
3093         final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3094                 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3095         final PackageUserState state = ps.readUserState(userId);
3096
3097         return PackageParser.generatePackageInfo(p, gids, flags,
3098                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3099     }
3100
3101     @Override
3102     public void checkPackageStartable(String packageName, int userId) {
3103         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3104
3105         synchronized (mPackages) {
3106             final PackageSetting ps = mSettings.mPackages.get(packageName);
3107             if (ps == null) {
3108                 throw new SecurityException("Package " + packageName + " was not found!");
3109             }
3110
3111             if (!ps.getInstalled(userId)) {
3112                 throw new SecurityException(
3113                         "Package " + packageName + " was not installed for user " + userId + "!");
3114             }
3115
3116             if (mSafeMode && !ps.isSystem()) {
3117                 throw new SecurityException("Package " + packageName + " not a system app!");
3118             }
3119
3120             if (mFrozenPackages.contains(packageName)) {
3121                 throw new SecurityException("Package " + packageName + " is currently frozen!");
3122             }
3123
3124             if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3125                     || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3126                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3127             }
3128         }
3129     }
3130
3131     @Override
3132     public boolean isPackageAvailable(String packageName, int userId) {
3133         if (!sUserManager.exists(userId)) return false;
3134         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3135                 false /* requireFullPermission */, false /* checkShell */, "is package available");
3136         synchronized (mPackages) {
3137             PackageParser.Package p = mPackages.get(packageName);
3138             if (p != null) {
3139                 final PackageSetting ps = (PackageSetting) p.mExtras;
3140                 if (ps != null) {
3141                     final PackageUserState state = ps.readUserState(userId);
3142                     if (state != null) {
3143                         return PackageParser.isAvailable(state);
3144                     }
3145                 }
3146             }
3147         }
3148         return false;
3149     }
3150
3151     @Override
3152     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3153         if (!sUserManager.exists(userId)) return null;
3154         flags = updateFlagsForPackage(flags, userId, packageName);
3155         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3156                 false /* requireFullPermission */, false /* checkShell */, "get package info");
3157
3158         // reader
3159         synchronized (mPackages) {
3160             // Normalize package name to hanlde renamed packages
3161             packageName = normalizePackageNameLPr(packageName);
3162
3163             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3164             PackageParser.Package p = null;
3165             if (matchFactoryOnly) {
3166                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3167                 if (ps != null) {
3168                     return generatePackageInfo(ps, flags, userId);
3169                 }
3170             }
3171             if (p == null) {
3172                 p = mPackages.get(packageName);
3173                 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3174                     return null;
3175                 }
3176             }
3177             if (DEBUG_PACKAGE_INFO)
3178                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3179             if (p != null) {
3180                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3181             }
3182             if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3183                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3184                 return generatePackageInfo(ps, flags, userId);
3185             }
3186         }
3187         return null;
3188     }
3189
3190     @Override
3191     public String[] currentToCanonicalPackageNames(String[] names) {
3192         String[] out = new String[names.length];
3193         // reader
3194         synchronized (mPackages) {
3195             for (int i=names.length-1; i>=0; i--) {
3196                 PackageSetting ps = mSettings.mPackages.get(names[i]);
3197                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3198             }
3199         }
3200         return out;
3201     }
3202
3203     @Override
3204     public String[] canonicalToCurrentPackageNames(String[] names) {
3205         String[] out = new String[names.length];
3206         // reader
3207         synchronized (mPackages) {
3208             for (int i=names.length-1; i>=0; i--) {
3209                 String cur = mSettings.mRenamedPackages.get(names[i]);
3210                 out[i] = cur != null ? cur : names[i];
3211             }
3212         }
3213         return out;
3214     }
3215
3216     @Override
3217     public int getPackageUid(String packageName, int flags, int userId) {
3218         if (!sUserManager.exists(userId)) return -1;
3219         flags = updateFlagsForPackage(flags, userId, packageName);
3220         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3221                 false /* requireFullPermission */, false /* checkShell */, "get package uid");
3222
3223         // reader
3224         synchronized (mPackages) {
3225             final PackageParser.Package p = mPackages.get(packageName);
3226             if (p != null && p.isMatch(flags)) {
3227                 return UserHandle.getUid(userId, p.applicationInfo.uid);
3228             }
3229             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3230                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3231                 if (ps != null && ps.isMatch(flags)) {
3232                     return UserHandle.getUid(userId, ps.appId);
3233                 }
3234             }
3235         }
3236
3237         return -1;
3238     }
3239
3240     @Override
3241     public int[] getPackageGids(String packageName, int flags, int userId) {
3242         if (!sUserManager.exists(userId)) return null;
3243         flags = updateFlagsForPackage(flags, userId, packageName);
3244         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3245                 false /* requireFullPermission */, false /* checkShell */,
3246                 "getPackageGids");
3247
3248         // reader
3249         synchronized (mPackages) {
3250             final PackageParser.Package p = mPackages.get(packageName);
3251             if (p != null && p.isMatch(flags)) {
3252                 PackageSetting ps = (PackageSetting) p.mExtras;
3253                 return ps.getPermissionsState().computeGids(userId);
3254             }
3255             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3256                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3257                 if (ps != null && ps.isMatch(flags)) {
3258                     return ps.getPermissionsState().computeGids(userId);
3259                 }
3260             }
3261         }
3262
3263         return null;
3264     }
3265
3266     static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3267         if (bp.perm != null) {
3268             return PackageParser.generatePermissionInfo(bp.perm, flags);
3269         }
3270         PermissionInfo pi = new PermissionInfo();
3271         pi.name = bp.name;
3272         pi.packageName = bp.sourcePackage;
3273         pi.nonLocalizedLabel = bp.name;
3274         pi.protectionLevel = bp.protectionLevel;
3275         return pi;
3276     }
3277
3278     @Override
3279     public PermissionInfo getPermissionInfo(String name, int flags) {
3280         // reader
3281         synchronized (mPackages) {
3282             final BasePermission p = mSettings.mPermissions.get(name);
3283             if (p != null) {
3284                 return generatePermissionInfo(p, flags);
3285             }
3286             return null;
3287         }
3288     }
3289
3290     @Override
3291     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3292             int flags) {
3293         // reader
3294         synchronized (mPackages) {
3295             if (group != null && !mPermissionGroups.containsKey(group)) {
3296                 // This is thrown as NameNotFoundException
3297                 return null;
3298             }
3299
3300             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3301             for (BasePermission p : mSettings.mPermissions.values()) {
3302                 if (group == null) {
3303                     if (p.perm == null || p.perm.info.group == null) {
3304                         out.add(generatePermissionInfo(p, flags));
3305                     }
3306                 } else {
3307                     if (p.perm != null && group.equals(p.perm.info.group)) {
3308                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3309                     }
3310                 }
3311             }
3312             return new ParceledListSlice<>(out);
3313         }
3314     }
3315
3316     @Override
3317     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3318         // reader
3319         synchronized (mPackages) {
3320             return PackageParser.generatePermissionGroupInfo(
3321                     mPermissionGroups.get(name), flags);
3322         }
3323     }
3324
3325     @Override
3326     public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3327         // reader
3328         synchronized (mPackages) {
3329             final int N = mPermissionGroups.size();
3330             ArrayList<PermissionGroupInfo> out
3331                     = new ArrayList<PermissionGroupInfo>(N);
3332             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3333                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3334             }
3335             return new ParceledListSlice<>(out);
3336         }
3337     }
3338
3339     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3340             int userId) {
3341         if (!sUserManager.exists(userId)) return null;
3342         PackageSetting ps = mSettings.mPackages.get(packageName);
3343         if (ps != null) {
3344             if (ps.pkg == null) {
3345                 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3346                 if (pInfo != null) {
3347                     return pInfo.applicationInfo;
3348                 }
3349                 return null;
3350             }
3351             return PackageParser.generateApplicationInfo(ps.pkg, flags,
3352                     ps.readUserState(userId), userId);
3353         }
3354         return null;
3355     }
3356
3357     @Override
3358     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3359         if (!sUserManager.exists(userId)) return null;
3360         flags = updateFlagsForApplication(flags, userId, packageName);
3361         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3362                 false /* requireFullPermission */, false /* checkShell */, "get application info");
3363
3364         // writer
3365         synchronized (mPackages) {
3366             // Normalize package name to hanlde renamed packages
3367             packageName = normalizePackageNameLPr(packageName);
3368
3369             PackageParser.Package p = mPackages.get(packageName);
3370             if (DEBUG_PACKAGE_INFO) Log.v(
3371                     TAG, "getApplicationInfo " + packageName
3372                     + ": " + p);
3373             if (p != null) {
3374                 PackageSetting ps = mSettings.mPackages.get(packageName);
3375                 if (ps == null) return null;
3376                 // Note: isEnabledLP() does not apply here - always return info
3377                 return PackageParser.generateApplicationInfo(
3378                         p, flags, ps.readUserState(userId), userId);
3379             }
3380             if ("android".equals(packageName)||"system".equals(packageName)) {
3381                 return mAndroidApplication;
3382             }
3383             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3384                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3385             }
3386         }
3387         return null;
3388     }
3389
3390     private String normalizePackageNameLPr(String packageName) {
3391         String normalizedPackageName = mSettings.mRenamedPackages.get(packageName);
3392         return normalizedPackageName != null ? normalizedPackageName : packageName;
3393     }
3394
3395     @Override
3396     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3397             final IPackageDataObserver observer) {
3398         mContext.enforceCallingOrSelfPermission(
3399                 android.Manifest.permission.CLEAR_APP_CACHE, null);
3400         // Queue up an async operation since clearing cache may take a little while.
3401         mHandler.post(new Runnable() {
3402             public void run() {
3403                 mHandler.removeCallbacks(this);
3404                 boolean success = true;
3405                 synchronized (mInstallLock) {
3406                     try {
3407                         mInstaller.freeCache(volumeUuid, freeStorageSize);
3408                     } catch (InstallerException e) {
3409                         Slog.w(TAG, "Couldn't clear application caches: " + e);
3410                         success = false;
3411                     }
3412                 }
3413                 if (observer != null) {
3414                     try {
3415                         observer.onRemoveCompleted(null, success);
3416                     } catch (RemoteException e) {
3417                         Slog.w(TAG, "RemoveException when invoking call back");
3418                     }
3419                 }
3420             }
3421         });
3422     }
3423
3424     @Override
3425     public void freeStorage(final String volumeUuid, final long freeStorageSize,
3426             final IntentSender pi) {
3427         mContext.enforceCallingOrSelfPermission(
3428                 android.Manifest.permission.CLEAR_APP_CACHE, null);
3429         // Queue up an async operation since clearing cache may take a little while.
3430         mHandler.post(new Runnable() {
3431             public void run() {
3432                 mHandler.removeCallbacks(this);
3433                 boolean success = true;
3434                 synchronized (mInstallLock) {
3435                     try {
3436                         mInstaller.freeCache(volumeUuid, freeStorageSize);
3437                     } catch (InstallerException e) {
3438                         Slog.w(TAG, "Couldn't clear application caches: " + e);
3439                         success = false;
3440                     }
3441                 }
3442                 if(pi != null) {
3443                     try {
3444                         // Callback via pending intent
3445                         int code = success ? 1 : 0;
3446                         pi.sendIntent(null, code, null,
3447                                 null, null);
3448                     } catch (SendIntentException e1) {
3449                         Slog.i(TAG, "Failed to send pending intent");
3450                     }
3451                 }
3452             }
3453         });
3454     }
3455
3456     void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3457         synchronized (mInstallLock) {
3458             try {
3459                 mInstaller.freeCache(volumeUuid, freeStorageSize);
3460             } catch (InstallerException e) {
3461                 throw new IOException("Failed to free enough space", e);
3462             }
3463         }
3464     }
3465
3466     /**
3467      * Update given flags based on encryption status of current user.
3468      */
3469     private int updateFlags(int flags, int userId) {
3470         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3471                 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3472             // Caller expressed an explicit opinion about what encryption
3473             // aware/unaware components they want to see, so fall through and
3474             // give them what they want
3475         } else {
3476             // Caller expressed no opinion, so match based on user state
3477             if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3478                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3479             } else {
3480                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3481             }
3482         }
3483         return flags;
3484     }
3485
3486     private UserManagerInternal getUserManagerInternal() {
3487         if (mUserManagerInternal == null) {
3488             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3489         }
3490         return mUserManagerInternal;
3491     }
3492
3493     /**
3494      * Update given flags when being used to request {@link PackageInfo}.
3495      */
3496     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3497         boolean triaged = true;
3498         if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3499                 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3500             // Caller is asking for component details, so they'd better be
3501             // asking for specific encryption matching behavior, or be triaged
3502             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3503                     | PackageManager.MATCH_DIRECT_BOOT_AWARE
3504                     | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3505                 triaged = false;
3506             }
3507         }
3508         if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3509                 | PackageManager.MATCH_SYSTEM_ONLY
3510                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3511             triaged = false;
3512         }
3513         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3514             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3515                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3516         }
3517         return updateFlags(flags, userId);
3518     }
3519
3520     /**
3521      * Update given flags when being used to request {@link ApplicationInfo}.
3522      */
3523     private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3524         return updateFlagsForPackage(flags, userId, cookie);
3525     }
3526
3527     /**
3528      * Update given flags when being used to request {@link ComponentInfo}.
3529      */
3530     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3531         if (cookie instanceof Intent) {
3532             if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3533                 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3534             }
3535         }
3536
3537         boolean triaged = true;
3538         // Caller is asking for component details, so they'd better be
3539         // asking for specific encryption matching behavior, or be triaged
3540         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3541                 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3542                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3543             triaged = false;
3544         }
3545         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3546             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3547                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3548         }
3549
3550         return updateFlags(flags, userId);
3551     }
3552
3553     /**
3554      * Update given flags when being used to request {@link ResolveInfo}.
3555      */
3556     int updateFlagsForResolve(int flags, int userId, Object cookie) {
3557         // Safe mode means we shouldn't match any third-party components
3558         if (mSafeMode) {
3559             flags |= PackageManager.MATCH_SYSTEM_ONLY;
3560         }
3561
3562         return updateFlagsForComponent(flags, userId, cookie);
3563     }
3564
3565     @Override
3566     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3567         if (!sUserManager.exists(userId)) return null;
3568         flags = updateFlagsForComponent(flags, userId, component);
3569         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3570                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
3571         synchronized (mPackages) {
3572             PackageParser.Activity a = mActivities.mActivities.get(component);
3573
3574             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3575             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3576                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3577                 if (ps == null) return null;
3578                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3579                         userId);
3580             }
3581             if (mResolveComponentName.equals(component)) {
3582                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
3583                         new PackageUserState(), userId);
3584             }
3585         }
3586         return null;
3587     }
3588
3589     @Override
3590     public boolean activitySupportsIntent(ComponentName component, Intent intent,
3591             String resolvedType) {
3592         synchronized (mPackages) {
3593             if (component.equals(mResolveComponentName)) {
3594                 // The resolver supports EVERYTHING!
3595                 return true;
3596             }
3597             PackageParser.Activity a = mActivities.mActivities.get(component);
3598             if (a == null) {
3599                 return false;
3600             }
3601             for (int i=0; i<a.intents.size(); i++) {
3602                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3603                         intent.getData(), intent.getCategories(), TAG) >= 0) {
3604                     return true;
3605                 }
3606             }
3607             return false;
3608         }
3609     }
3610
3611     @Override
3612     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3613         if (!sUserManager.exists(userId)) return null;
3614         flags = updateFlagsForComponent(flags, userId, component);
3615         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3616                 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
3617         synchronized (mPackages) {
3618             PackageParser.Activity a = mReceivers.mActivities.get(component);
3619             if (DEBUG_PACKAGE_INFO) Log.v(
3620                 TAG, "getReceiverInfo " + component + ": " + a);
3621             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3622                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3623                 if (ps == null) return null;
3624                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3625                         userId);
3626             }
3627         }
3628         return null;
3629     }
3630
3631     @Override
3632     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3633         if (!sUserManager.exists(userId)) return null;
3634         flags = updateFlagsForComponent(flags, userId, component);
3635         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3636                 false /* requireFullPermission */, false /* checkShell */, "get service info");
3637         synchronized (mPackages) {
3638             PackageParser.Service s = mServices.mServices.get(component);
3639             if (DEBUG_PACKAGE_INFO) Log.v(
3640                 TAG, "getServiceInfo " + component + ": " + s);
3641             if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3642                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3643                 if (ps == null) return null;
3644                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3645                         userId);
3646             }
3647         }
3648         return null;
3649     }
3650
3651     @Override
3652     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3653         if (!sUserManager.exists(userId)) return null;
3654         flags = updateFlagsForComponent(flags, userId, component);
3655         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3656                 false /* requireFullPermission */, false /* checkShell */, "get provider info");
3657         synchronized (mPackages) {
3658             PackageParser.Provider p = mProviders.mProviders.get(component);
3659             if (DEBUG_PACKAGE_INFO) Log.v(
3660                 TAG, "getProviderInfo " + component + ": " + p);
3661             if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3662                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3663                 if (ps == null) return null;
3664                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3665                         userId);
3666             }
3667         }
3668         return null;
3669     }
3670
3671     @Override
3672     public String[] getSystemSharedLibraryNames() {
3673         Set<String> libSet;
3674         synchronized (mPackages) {
3675             libSet = mSharedLibraries.keySet();
3676             int size = libSet.size();
3677             if (size > 0) {
3678                 String[] libs = new String[size];
3679                 libSet.toArray(libs);
3680                 return libs;
3681             }
3682         }
3683         return null;
3684     }
3685
3686     @Override
3687     public @NonNull String getServicesSystemSharedLibraryPackageName() {
3688         synchronized (mPackages) {
3689             return mServicesSystemSharedLibraryPackageName;
3690         }
3691     }
3692
3693     @Override
3694     public @NonNull String getSharedSystemSharedLibraryPackageName() {
3695         synchronized (mPackages) {
3696             return mSharedSystemSharedLibraryPackageName;
3697         }
3698     }
3699
3700     @Override
3701     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
3702         synchronized (mPackages) {
3703             final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
3704
3705             final FeatureInfo fi = new FeatureInfo();
3706             fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3707                     FeatureInfo.GL_ES_VERSION_UNDEFINED);
3708             res.add(fi);
3709
3710             return new ParceledListSlice<>(res);
3711         }
3712     }
3713
3714     @Override
3715     public boolean hasSystemFeature(String name, int version) {
3716         synchronized (mPackages) {
3717             final FeatureInfo feat = mAvailableFeatures.get(name);
3718             if (feat == null) {
3719                 return false;
3720             } else {
3721                 return feat.version >= version;
3722             }
3723         }
3724     }
3725
3726     @Override
3727     public int checkPermission(String permName, String pkgName, int userId) {
3728         if (!sUserManager.exists(userId)) {
3729             return PackageManager.PERMISSION_DENIED;
3730         }
3731
3732         synchronized (mPackages) {
3733             final PackageParser.Package p = mPackages.get(pkgName);
3734             if (p != null && p.mExtras != null) {
3735                 final PackageSetting ps = (PackageSetting) p.mExtras;
3736                 final PermissionsState permissionsState = ps.getPermissionsState();
3737                 if (permissionsState.hasPermission(permName, userId)) {
3738                     return PackageManager.PERMISSION_GRANTED;
3739                 }
3740                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3741                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3742                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3743                     return PackageManager.PERMISSION_GRANTED;
3744                 }
3745             }
3746         }
3747
3748         return PackageManager.PERMISSION_DENIED;
3749     }
3750
3751     @Override
3752     public int checkUidPermission(String permName, int uid) {
3753         final int userId = UserHandle.getUserId(uid);
3754
3755         if (!sUserManager.exists(userId)) {
3756             return PackageManager.PERMISSION_DENIED;
3757         }
3758
3759         synchronized (mPackages) {
3760             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3761             if (obj != null) {
3762                 final SettingBase ps = (SettingBase) obj;
3763                 final PermissionsState permissionsState = ps.getPermissionsState();
3764                 if (permissionsState.hasPermission(permName, userId)) {
3765                     return PackageManager.PERMISSION_GRANTED;
3766                 }
3767                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3768                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3769                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3770                     return PackageManager.PERMISSION_GRANTED;
3771                 }
3772             } else {
3773                 ArraySet<String> perms = mSystemPermissions.get(uid);
3774                 if (perms != null) {
3775                     if (perms.contains(permName)) {
3776                         return PackageManager.PERMISSION_GRANTED;
3777                     }
3778                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3779                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3780                         return PackageManager.PERMISSION_GRANTED;
3781                     }
3782                 }
3783             }
3784         }
3785
3786         return PackageManager.PERMISSION_DENIED;
3787     }
3788
3789     @Override
3790     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3791         if (UserHandle.getCallingUserId() != userId) {
3792             mContext.enforceCallingPermission(
3793                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3794                     "isPermissionRevokedByPolicy for user " + userId);
3795         }
3796
3797         if (checkPermission(permission, packageName, userId)
3798                 == PackageManager.PERMISSION_GRANTED) {
3799             return false;
3800         }
3801
3802         final long identity = Binder.clearCallingIdentity();
3803         try {
3804             final int flags = getPermissionFlags(permission, packageName, userId);
3805             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3806         } finally {
3807             Binder.restoreCallingIdentity(identity);
3808         }
3809     }
3810
3811     @Override
3812     public String getPermissionControllerPackageName() {
3813         synchronized (mPackages) {
3814             return mRequiredInstallerPackage;
3815         }
3816     }
3817
3818     /**
3819      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3820      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3821      * @param checkShell whether to prevent shell from access if there's a debugging restriction
3822      * @param message the message to log on security exception
3823      */
3824     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3825             boolean checkShell, String message) {
3826         enforceCrossUserPermission(
3827               callingUid,
3828               userId,
3829               requireFullPermission,
3830               checkShell,
3831               false,
3832               message);
3833     }
3834
3835     private void enforceCrossUserPermission(int callingUid, int userId,
3836             boolean requireFullPermission, boolean checkShell,
3837             boolean requirePermissionWhenSameUser, String message) {
3838         if (userId < 0) {
3839             throw new IllegalArgumentException("Invalid userId " + userId);
3840         }
3841         if (checkShell) {
3842             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3843         }
3844         if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
3845         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3846             if (requireFullPermission) {
3847                 mContext.enforceCallingOrSelfPermission(
3848                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3849             } else {
3850                 try {
3851                     mContext.enforceCallingOrSelfPermission(
3852                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3853                 } catch (SecurityException se) {
3854                     mContext.enforceCallingOrSelfPermission(
3855                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3856                 }
3857             }
3858         }
3859     }
3860
3861     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3862         if (callingUid == Process.SHELL_UID) {
3863             if (userHandle >= 0
3864                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
3865                 throw new SecurityException("Shell does not have permission to access user "
3866                         + userHandle);
3867             } else if (userHandle < 0) {
3868                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3869                         + Debug.getCallers(3));
3870             }
3871         }
3872     }
3873
3874     private BasePermission findPermissionTreeLP(String permName) {
3875         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3876             if (permName.startsWith(bp.name) &&
3877                     permName.length() > bp.name.length() &&
3878                     permName.charAt(bp.name.length()) == '.') {
3879                 return bp;
3880             }
3881         }
3882         return null;
3883     }
3884
3885     private BasePermission checkPermissionTreeLP(String permName) {
3886         if (permName != null) {
3887             BasePermission bp = findPermissionTreeLP(permName);
3888             if (bp != null) {
3889                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3890                     return bp;
3891                 }
3892                 throw new SecurityException("Calling uid "
3893                         + Binder.getCallingUid()
3894                         + " is not allowed to add to permission tree "
3895                         + bp.name + " owned by uid " + bp.uid);
3896             }
3897         }
3898         throw new SecurityException("No permission tree found for " + permName);
3899     }
3900
3901     static boolean compareStrings(CharSequence s1, CharSequence s2) {
3902         if (s1 == null) {
3903             return s2 == null;
3904         }
3905         if (s2 == null) {
3906             return false;
3907         }
3908         if (s1.getClass() != s2.getClass()) {
3909             return false;
3910         }
3911         return s1.equals(s2);
3912     }
3913
3914     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3915         if (pi1.icon != pi2.icon) return false;
3916         if (pi1.logo != pi2.logo) return false;
3917         if (pi1.protectionLevel != pi2.protectionLevel) return false;
3918         if (!compareStrings(pi1.name, pi2.name)) return false;
3919         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3920         // We'll take care of setting this one.
3921         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3922         // These are not currently stored in settings.
3923         //if (!compareStrings(pi1.group, pi2.group)) return false;
3924         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3925         //if (pi1.labelRes != pi2.labelRes) return false;
3926         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3927         return true;
3928     }
3929
3930     int permissionInfoFootprint(PermissionInfo info) {
3931         int size = info.name.length();
3932         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3933         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3934         return size;
3935     }
3936
3937     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3938         int size = 0;
3939         for (BasePermission perm : mSettings.mPermissions.values()) {
3940             if (perm.uid == tree.uid) {
3941                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3942             }
3943         }
3944         return size;
3945     }
3946
3947     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3948         // We calculate the max size of permissions defined by this uid and throw
3949         // if that plus the size of 'info' would exceed our stated maximum.
3950         if (tree.uid != Process.SYSTEM_UID) {
3951             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3952             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3953                 throw new SecurityException("Permission tree size cap exceeded");
3954             }
3955         }
3956     }
3957
3958     boolean addPermissionLocked(PermissionInfo info, boolean async) {
3959         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3960             throw new SecurityException("Label must be specified in permission");
3961         }
3962         BasePermission tree = checkPermissionTreeLP(info.name);
3963         BasePermission bp = mSettings.mPermissions.get(info.name);
3964         boolean added = bp == null;
3965         boolean changed = true;
3966         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3967         if (added) {
3968             enforcePermissionCapLocked(info, tree);
3969             bp = new BasePermission(info.name, tree.sourcePackage,
3970                     BasePermission.TYPE_DYNAMIC);
3971         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3972             throw new SecurityException(
3973                     "Not allowed to modify non-dynamic permission "
3974                     + info.name);
3975         } else {
3976             if ((bp.perm == null) || (tree.perm == null)) {
3977                 Slog.w(TAG, "Base or tree permission is null: " + bp.perm + ", " + tree.perm);
3978                 return false;
3979             }
3980             if (bp.protectionLevel == fixedLevel
3981                     && bp.perm.owner.equals(tree.perm.owner)
3982                     && bp.uid == tree.uid
3983                     && comparePermissionInfos(bp.perm.info, info)) {
3984                 changed = false;
3985             }
3986         }
3987         bp.protectionLevel = fixedLevel;
3988         info = new PermissionInfo(info);
3989         info.protectionLevel = fixedLevel;
3990         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3991         bp.perm.info.packageName = tree.perm.info.packageName;
3992         bp.uid = tree.uid;
3993         if (added) {
3994             mSettings.mPermissions.put(info.name, bp);
3995         }
3996         if (changed) {
3997             if (!async) {
3998                 mSettings.writeLPr();
3999             } else {
4000                 scheduleWriteSettingsLocked();
4001             }
4002         }
4003         return added;
4004     }
4005
4006     @Override
4007     public boolean addPermission(PermissionInfo info) {
4008         synchronized (mPackages) {
4009             return addPermissionLocked(info, false);
4010         }
4011     }
4012
4013     @Override
4014     public boolean addPermissionAsync(PermissionInfo info) {
4015         synchronized (mPackages) {
4016             return addPermissionLocked(info, true);
4017         }
4018     }
4019
4020     @Override
4021     public void removePermission(String name) {
4022         synchronized (mPackages) {
4023             checkPermissionTreeLP(name);
4024             BasePermission bp = mSettings.mPermissions.get(name);
4025             if (bp != null) {
4026                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
4027                     throw new SecurityException(
4028                             "Not allowed to modify non-dynamic permission "
4029                             + name);
4030                 }
4031                 mSettings.mPermissions.remove(name);
4032                 mSettings.writeLPr();
4033             }
4034         }
4035     }
4036
4037     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4038             BasePermission bp) {
4039         int index = pkg.requestedPermissions.indexOf(bp.name);
4040         if (index == -1) {
4041             throw new SecurityException("Package " + pkg.packageName
4042                     + " has not requested permission " + bp.name);
4043         }
4044         if (!bp.isRuntime() && !bp.isDevelopment()) {
4045             throw new SecurityException("Permission " + bp.name
4046                     + " is not a changeable permission type");
4047         }
4048     }
4049
4050     @Override
4051     public void grantRuntimePermission(String packageName, String name, final int userId) {
4052         if (!sUserManager.exists(userId)) {
4053             Log.e(TAG, "No such user:" + userId);
4054             return;
4055         }
4056
4057         mContext.enforceCallingOrSelfPermission(
4058                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4059                 "grantRuntimePermission");
4060
4061         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4062                 true /* requireFullPermission */, true /* checkShell */,
4063                 "grantRuntimePermission");
4064
4065         final int uid;
4066         final SettingBase sb;
4067
4068         synchronized (mPackages) {
4069             final PackageParser.Package pkg = mPackages.get(packageName);
4070             if (pkg == null) {
4071                 throw new IllegalArgumentException("Unknown package: " + packageName);
4072             }
4073
4074             final BasePermission bp = mSettings.mPermissions.get(name);
4075             if (bp == null) {
4076                 throw new IllegalArgumentException("Unknown permission: " + name);
4077             }
4078
4079             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4080
4081             // If a permission review is required for legacy apps we represent
4082             // their permissions as always granted runtime ones since we need
4083             // to keep the review required permission flag per user while an
4084             // install permission's state is shared across all users.
4085             if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
4086                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4087                     && bp.isRuntime()) {
4088                 return;
4089             }
4090
4091             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4092             sb = (SettingBase) pkg.mExtras;
4093             if (sb == null) {
4094                 throw new IllegalArgumentException("Unknown package: " + packageName);
4095             }
4096
4097             final PermissionsState permissionsState = sb.getPermissionsState();
4098
4099             final int flags = permissionsState.getPermissionFlags(name, userId);
4100             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4101                 throw new SecurityException("Cannot grant system fixed permission "
4102                         + name + " for package " + packageName);
4103             }
4104
4105             if (bp.isDevelopment()) {
4106                 // Development permissions must be handled specially, since they are not
4107                 // normal runtime permissions.  For now they apply to all users.
4108                 if (permissionsState.grantInstallPermission(bp) !=
4109                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4110                     scheduleWriteSettingsLocked();
4111                 }
4112                 return;
4113             }
4114
4115             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4116                 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4117                 return;
4118             }
4119
4120             final int result = permissionsState.grantRuntimePermission(bp, userId);
4121             switch (result) {
4122                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4123                     return;
4124                 }
4125
4126                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4127                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4128                     mHandler.post(new Runnable() {
4129                         @Override
4130                         public void run() {
4131                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4132                         }
4133                     });
4134                 }
4135                 break;
4136             }
4137
4138             mOnPermissionChangeListeners.onPermissionsChanged(uid);
4139
4140             // Not critical if that is lost - app has to request again.
4141             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4142         }
4143
4144         // Only need to do this if user is initialized. Otherwise it's a new user
4145         // and there are no processes running as the user yet and there's no need
4146         // to make an expensive call to remount processes for the changed permissions.
4147         if (READ_EXTERNAL_STORAGE.equals(name)
4148                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
4149             final long token = Binder.clearCallingIdentity();
4150             try {
4151                 if (sUserManager.isInitialized(userId)) {
4152                     MountServiceInternal mountServiceInternal = LocalServices.getService(
4153                             MountServiceInternal.class);
4154                     mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
4155                 }
4156             } finally {
4157                 Binder.restoreCallingIdentity(token);
4158             }
4159         }
4160     }
4161
4162     @Override
4163     public void revokeRuntimePermission(String packageName, String name, int userId) {
4164         if (!sUserManager.exists(userId)) {
4165             Log.e(TAG, "No such user:" + userId);
4166             return;
4167         }
4168
4169         mContext.enforceCallingOrSelfPermission(
4170                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4171                 "revokeRuntimePermission");
4172
4173         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4174                 true /* requireFullPermission */, true /* checkShell */,
4175                 "revokeRuntimePermission");
4176
4177         final int appId;
4178
4179         synchronized (mPackages) {
4180             final PackageParser.Package pkg = mPackages.get(packageName);
4181             if (pkg == null) {
4182                 throw new IllegalArgumentException("Unknown package: " + packageName);
4183             }
4184
4185             final BasePermission bp = mSettings.mPermissions.get(name);
4186             if (bp == null) {
4187                 throw new IllegalArgumentException("Unknown permission: " + name);
4188             }
4189
4190             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4191
4192             // If a permission review is required for legacy apps we represent
4193             // their permissions as always granted runtime ones since we need
4194             // to keep the review required permission flag per user while an
4195             // install permission's state is shared across all users.
4196             if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
4197                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4198                     && bp.isRuntime()) {
4199                 return;
4200             }
4201
4202             SettingBase sb = (SettingBase) pkg.mExtras;
4203             if (sb == null) {
4204                 throw new IllegalArgumentException("Unknown package: " + packageName);
4205             }
4206
4207             final PermissionsState permissionsState = sb.getPermissionsState();
4208
4209             final int flags = permissionsState.getPermissionFlags(name, userId);
4210             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4211                 throw new SecurityException("Cannot revoke system fixed permission "
4212                         + name + " for package " + packageName);
4213             }
4214
4215             if (bp.isDevelopment()) {
4216                 // Development permissions must be handled specially, since they are not
4217                 // normal runtime permissions.  For now they apply to all users.
4218                 if (permissionsState.revokeInstallPermission(bp) !=
4219                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4220                     scheduleWriteSettingsLocked();
4221                 }
4222                 return;
4223             }
4224
4225             if (permissionsState.revokeRuntimePermission(bp, userId) ==
4226                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
4227                 return;
4228             }
4229
4230             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4231
4232             // Critical, after this call app should never have the permission.
4233             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4234
4235             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4236         }
4237
4238         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4239     }
4240
4241     /**
4242      * We might auto-grant permissions if any permission of the group is already granted. Hence if
4243      * the group of a granted permission changes we need to revoke it to avoid having permissions of
4244      * the new group auto-granted.
4245      *
4246      * @param newPackage The new package that was installed
4247      * @param oldPackage The old package that was updated
4248      * @param allPackageNames All package names
4249      */
4250     private void revokeRuntimePermissionsIfGroupChanged(
4251             PackageParser.Package newPackage,
4252             PackageParser.Package oldPackage,
4253             ArrayList<String> allPackageNames) {
4254         final int numOldPackagePermissions = oldPackage.permissions.size();
4255         final ArrayMap<String, String> oldPermissionNameToGroupName
4256                 = new ArrayMap<>(numOldPackagePermissions);
4257
4258         for (int i = 0; i < numOldPackagePermissions; i++) {
4259             final PackageParser.Permission permission = oldPackage.permissions.get(i);
4260
4261             if (permission.group != null) {
4262                 oldPermissionNameToGroupName.put(permission.info.name,
4263                         permission.group.info.name);
4264             }
4265         }
4266
4267         final int numNewPackagePermissions = newPackage.permissions.size();
4268         for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
4269                 newPermissionNum++) {
4270             final PackageParser.Permission newPermission =
4271                     newPackage.permissions.get(newPermissionNum);
4272             final int newProtection = newPermission.info.protectionLevel;
4273
4274             if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
4275                 final String permissionName = newPermission.info.name;
4276                 final String newPermissionGroupName =
4277                         newPermission.group == null ? null : newPermission.group.info.name;
4278                 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
4279                         permissionName);
4280
4281                 if (newPermissionGroupName != null
4282                         && !newPermissionGroupName.equals(oldPermissionGroupName)) {
4283                     final List<UserInfo> users = mContext.getSystemService(UserManager.class)
4284                             .getUsers();
4285
4286                     final int numUsers = users.size();
4287                     for (int userNum = 0; userNum < numUsers; userNum++) {
4288                         final int userId = users.get(userNum).id;
4289                         final int numPackages = allPackageNames.size();
4290                         for (int packageNum = 0; packageNum < numPackages; packageNum++) {
4291                             final String packageName = allPackageNames.get(packageNum);
4292
4293                             if (checkPermission(permissionName, packageName, userId)
4294                                     == PackageManager.PERMISSION_GRANTED) {
4295                                 EventLog.writeEvent(0x534e4554, "72710897",
4296                                         newPackage.applicationInfo.uid,
4297                                         "Revoking permission", permissionName, "from package",
4298                                         packageName, "as the group changed from",
4299                                         oldPermissionGroupName, "to", newPermissionGroupName);
4300
4301                                 try {
4302                                     revokeRuntimePermission(packageName, permissionName, userId);
4303                                 } catch (IllegalArgumentException e) {
4304                                     Slog.e(TAG, "Could not revoke " + permissionName + " from "
4305                                             + packageName, e);
4306                                 }
4307                             }
4308                         }
4309                     }
4310                 }
4311             }
4312         }
4313     }
4314
4315
4316     @Override
4317     public void resetRuntimePermissions() {
4318         mContext.enforceCallingOrSelfPermission(
4319                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4320                 "revokeRuntimePermission");
4321
4322         int callingUid = Binder.getCallingUid();
4323         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4324             mContext.enforceCallingOrSelfPermission(
4325                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4326                     "resetRuntimePermissions");
4327         }
4328
4329         synchronized (mPackages) {
4330             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
4331             for (int userId : UserManagerService.getInstance().getUserIds()) {
4332                 final int packageCount = mPackages.size();
4333                 for (int i = 0; i < packageCount; i++) {
4334                     PackageParser.Package pkg = mPackages.valueAt(i);
4335                     if (!(pkg.mExtras instanceof PackageSetting)) {
4336                         continue;
4337                     }
4338                     PackageSetting ps = (PackageSetting) pkg.mExtras;
4339                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
4340                 }
4341             }
4342         }
4343     }
4344
4345     @Override
4346     public int getPermissionFlags(String name, String packageName, int userId) {
4347         if (!sUserManager.exists(userId)) {
4348             return 0;
4349         }
4350
4351         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
4352
4353         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4354                 true /* requireFullPermission */, false /* checkShell */,
4355                 "getPermissionFlags");
4356
4357         synchronized (mPackages) {
4358             final PackageParser.Package pkg = mPackages.get(packageName);
4359             if (pkg == null) {
4360                 return 0;
4361             }
4362
4363             final BasePermission bp = mSettings.mPermissions.get(name);
4364             if (bp == null) {
4365                 return 0;
4366             }
4367
4368             SettingBase sb = (SettingBase) pkg.mExtras;
4369             if (sb == null) {
4370                 return 0;
4371             }
4372
4373             PermissionsState permissionsState = sb.getPermissionsState();
4374             return permissionsState.getPermissionFlags(name, userId);
4375         }
4376     }
4377
4378     @Override
4379     public void updatePermissionFlags(String name, String packageName, int flagMask,
4380             int flagValues, int userId) {
4381         if (!sUserManager.exists(userId)) {
4382             return;
4383         }
4384
4385         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
4386
4387         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4388                 true /* requireFullPermission */, true /* checkShell */,
4389                 "updatePermissionFlags");
4390
4391         // Only the system can change these flags and nothing else.
4392         if (getCallingUid() != Process.SYSTEM_UID) {
4393             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4394             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4395             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4396             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4397             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
4398         }
4399
4400         synchronized (mPackages) {
4401             final PackageParser.Package pkg = mPackages.get(packageName);
4402             if (pkg == null) {
4403                 throw new IllegalArgumentException("Unknown package: " + packageName);
4404             }
4405
4406             final BasePermission bp = mSettings.mPermissions.get(name);
4407             if (bp == null) {
4408                 throw new IllegalArgumentException("Unknown permission: " + name);
4409             }
4410
4411             SettingBase sb = (SettingBase) pkg.mExtras;
4412             if (sb == null) {
4413                 throw new IllegalArgumentException("Unknown package: " + packageName);
4414             }
4415
4416             PermissionsState permissionsState = sb.getPermissionsState();
4417
4418             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
4419
4420             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
4421                 // Install and runtime permissions are stored in different places,
4422                 // so figure out what permission changed and persist the change.
4423                 if (permissionsState.getInstallPermissionState(name) != null) {
4424                     scheduleWriteSettingsLocked();
4425                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
4426                         || hadState) {
4427                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4428                 }
4429             }
4430         }
4431     }
4432
4433     /**
4434      * Update the permission flags for all packages and runtime permissions of a user in order
4435      * to allow device or profile owner to remove POLICY_FIXED.
4436      */
4437     @Override
4438     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
4439         if (!sUserManager.exists(userId)) {
4440             return;
4441         }
4442
4443         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
4444
4445         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4446                 true /* requireFullPermission */, true /* checkShell */,
4447                 "updatePermissionFlagsForAllApps");
4448
4449         // Only the system can change system fixed flags.
4450         if (getCallingUid() != Process.SYSTEM_UID) {
4451             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4452             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4453         }
4454
4455         synchronized (mPackages) {
4456             boolean changed = false;
4457             final int packageCount = mPackages.size();
4458             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4459                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4460                 SettingBase sb = (SettingBase) pkg.mExtras;
4461                 if (sb == null) {
4462                     continue;
4463                 }
4464                 PermissionsState permissionsState = sb.getPermissionsState();
4465                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4466                         userId, flagMask, flagValues);
4467             }
4468             if (changed) {
4469                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4470             }
4471         }
4472     }
4473
4474     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4475         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4476                 != PackageManager.PERMISSION_GRANTED
4477             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4478                 != PackageManager.PERMISSION_GRANTED) {
4479             throw new SecurityException(message + " requires "
4480                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4481                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4482         }
4483     }
4484
4485     @Override
4486     public boolean shouldShowRequestPermissionRationale(String permissionName,
4487             String packageName, int userId) {
4488         if (UserHandle.getCallingUserId() != userId) {
4489             mContext.enforceCallingPermission(
4490                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4491                     "canShowRequestPermissionRationale for user " + userId);
4492         }
4493
4494         final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
4495         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4496             return false;
4497         }
4498
4499         if (checkPermission(permissionName, packageName, userId)
4500                 == PackageManager.PERMISSION_GRANTED) {
4501             return false;
4502         }
4503
4504         final int flags;
4505
4506         final long identity = Binder.clearCallingIdentity();
4507         try {
4508             flags = getPermissionFlags(permissionName,
4509                     packageName, userId);
4510         } finally {
4511             Binder.restoreCallingIdentity(identity);
4512         }
4513
4514         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4515                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4516                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
4517
4518         if ((flags & fixedFlags) != 0) {
4519             return false;
4520         }
4521
4522         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4523     }
4524
4525     @Override
4526     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4527         mContext.enforceCallingOrSelfPermission(
4528                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4529                 "addOnPermissionsChangeListener");
4530
4531         synchronized (mPackages) {
4532             mOnPermissionChangeListeners.addListenerLocked(listener);
4533         }
4534     }
4535
4536     @Override
4537     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4538         synchronized (mPackages) {
4539             mOnPermissionChangeListeners.removeListenerLocked(listener);
4540         }
4541     }
4542
4543     @Override
4544     public boolean isProtectedBroadcast(String actionName) {
4545         synchronized (mPackages) {
4546             if (mProtectedBroadcasts.contains(actionName)) {
4547                 return true;
4548             } else if (actionName != null) {
4549                 // TODO: remove these terrible hacks
4550                 if (actionName.startsWith("android.net.netmon.lingerExpired")
4551                         || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
4552                         || actionName.startsWith("com.android.internal.telephony.data-reconnect")
4553                         || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
4554                     return true;
4555                 }
4556             }
4557         }
4558         return false;
4559     }
4560
4561     @Override
4562     public int checkSignatures(String pkg1, String pkg2) {
4563         synchronized (mPackages) {
4564             final PackageParser.Package p1 = mPackages.get(pkg1);
4565             final PackageParser.Package p2 = mPackages.get(pkg2);
4566             if (p1 == null || p1.mExtras == null
4567                     || p2 == null || p2.mExtras == null) {
4568                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4569             }
4570             return compareSignatures(p1.mSignatures, p2.mSignatures);
4571         }
4572     }
4573
4574     @Override
4575     public int checkUidSignatures(int uid1, int uid2) {
4576         // Map to base uids.
4577         uid1 = UserHandle.getAppId(uid1);
4578         uid2 = UserHandle.getAppId(uid2);
4579         // reader
4580         synchronized (mPackages) {
4581             Signature[] s1;
4582             Signature[] s2;
4583             Object obj = mSettings.getUserIdLPr(uid1);
4584             if (obj != null) {
4585                 if (obj instanceof SharedUserSetting) {
4586                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4587                 } else if (obj instanceof PackageSetting) {
4588                     s1 = ((PackageSetting)obj).signatures.mSignatures;
4589                 } else {
4590                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4591                 }
4592             } else {
4593                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4594             }
4595             obj = mSettings.getUserIdLPr(uid2);
4596             if (obj != null) {
4597                 if (obj instanceof SharedUserSetting) {
4598                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4599                 } else if (obj instanceof PackageSetting) {
4600                     s2 = ((PackageSetting)obj).signatures.mSignatures;
4601                 } else {
4602                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4603                 }
4604             } else {
4605                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4606             }
4607             return compareSignatures(s1, s2);
4608         }
4609     }
4610
4611     /**
4612      * This method should typically only be used when granting or revoking
4613      * permissions, since the app may immediately restart after this call.
4614      * <p>
4615      * If you're doing surgery on app code/data, use {@link PackageFreezer} to
4616      * guard your work against the app being relaunched.
4617      */
4618     private void killUid(int appId, int userId, String reason) {
4619         final long identity = Binder.clearCallingIdentity();
4620         try {
4621             IActivityManager am = ActivityManagerNative.getDefault();
4622             if (am != null) {
4623                 try {
4624                     am.killUid(appId, userId, reason);
4625                 } catch (RemoteException e) {
4626                     /* ignore - same process */
4627                 }
4628             }
4629         } finally {
4630             Binder.restoreCallingIdentity(identity);
4631         }
4632     }
4633
4634     /**
4635      * Compares two sets of signatures. Returns:
4636      * <br />
4637      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4638      * <br />
4639      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4640      * <br />
4641      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4642      * <br />
4643      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4644      * <br />
4645      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4646      */
4647     static int compareSignatures(Signature[] s1, Signature[] s2) {
4648         if (s1 == null) {
4649             return s2 == null
4650                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
4651                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4652         }
4653
4654         if (s2 == null) {
4655             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4656         }
4657
4658         if (s1.length != s2.length) {
4659             return PackageManager.SIGNATURE_NO_MATCH;
4660         }
4661
4662         // Since both signature sets are of size 1, we can compare without HashSets.
4663         if (s1.length == 1) {
4664             return s1[0].equals(s2[0]) ?
4665                     PackageManager.SIGNATURE_MATCH :
4666                     PackageManager.SIGNATURE_NO_MATCH;
4667         }
4668
4669         ArraySet<Signature> set1 = new ArraySet<Signature>();
4670         for (Signature sig : s1) {
4671             set1.add(sig);
4672         }
4673         ArraySet<Signature> set2 = new ArraySet<Signature>();
4674         for (Signature sig : s2) {
4675             set2.add(sig);
4676         }
4677         // Make sure s2 contains all signatures in s1.
4678         if (set1.equals(set2)) {
4679             return PackageManager.SIGNATURE_MATCH;
4680         }
4681         return PackageManager.SIGNATURE_NO_MATCH;
4682     }
4683
4684     /**
4685      * If the database version for this type of package (internal storage or
4686      * external storage) is less than the version where package signatures
4687      * were updated, return true.
4688      */
4689     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4690         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4691         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4692     }
4693
4694     /**
4695      * Used for backward compatibility to make sure any packages with
4696      * certificate chains get upgraded to the new style. {@code existingSigs}
4697      * will be in the old format (since they were stored on disk from before the
4698      * system upgrade) and {@code scannedSigs} will be in the newer format.
4699      */
4700     private int compareSignaturesCompat(PackageSignatures existingSigs,
4701             PackageParser.Package scannedPkg) {
4702         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4703             return PackageManager.SIGNATURE_NO_MATCH;
4704         }
4705
4706         ArraySet<Signature> existingSet = new ArraySet<Signature>();
4707         for (Signature sig : existingSigs.mSignatures) {
4708             existingSet.add(sig);
4709         }
4710         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4711         for (Signature sig : scannedPkg.mSignatures) {
4712             try {
4713                 Signature[] chainSignatures = sig.getChainSignatures();
4714                 for (Signature chainSig : chainSignatures) {
4715                     scannedCompatSet.add(chainSig);
4716                 }
4717             } catch (CertificateEncodingException e) {
4718                 scannedCompatSet.add(sig);
4719             }
4720         }
4721         /*
4722          * Make sure the expanded scanned set contains all signatures in the
4723          * existing one.
4724          */
4725         if (scannedCompatSet.equals(existingSet)) {
4726             // Migrate the old signatures to the new scheme.
4727             existingSigs.assignSignatures(scannedPkg.mSignatures);
4728             // The new KeySets will be re-added later in the scanning process.
4729             synchronized (mPackages) {
4730                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4731             }
4732             return PackageManager.SIGNATURE_MATCH;
4733         }
4734         return PackageManager.SIGNATURE_NO_MATCH;
4735     }
4736
4737     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4738         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4739         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4740     }
4741
4742     private int compareSignaturesRecover(PackageSignatures existingSigs,
4743             PackageParser.Package scannedPkg) {
4744         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4745             return PackageManager.SIGNATURE_NO_MATCH;
4746         }
4747
4748         String msg = null;
4749         try {
4750             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4751                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4752                         + scannedPkg.packageName);
4753                 return PackageManager.SIGNATURE_MATCH;
4754             }
4755         } catch (CertificateException e) {
4756             msg = e.getMessage();
4757         }
4758
4759         logCriticalInfo(Log.INFO,
4760                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4761         return PackageManager.SIGNATURE_NO_MATCH;
4762     }
4763
4764     @Override
4765     public List<String> getAllPackages() {
4766         synchronized (mPackages) {
4767             return new ArrayList<String>(mPackages.keySet());
4768         }
4769     }
4770
4771     @Override
4772     public String[] getPackagesForUid(int uid) {
4773         uid = UserHandle.getAppId(uid);
4774         // reader
4775         synchronized (mPackages) {
4776             Object obj = mSettings.getUserIdLPr(uid);
4777             if (obj instanceof SharedUserSetting) {
4778                 final SharedUserSetting sus = (SharedUserSetting) obj;
4779                 final int N = sus.packages.size();
4780                 final String[] res = new String[N];
4781                 for (int i = 0; i < N; i++) {
4782                     res[i] = sus.packages.valueAt(i).name;
4783                 }
4784                 return res;
4785             } else if (obj instanceof PackageSetting) {
4786                 final PackageSetting ps = (PackageSetting) obj;
4787                 return new String[] { ps.name };
4788             }
4789         }
4790         return null;
4791     }
4792
4793     @Override
4794     public String getNameForUid(int uid) {
4795         // reader
4796         synchronized (mPackages) {
4797             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4798             if (obj instanceof SharedUserSetting) {
4799                 final SharedUserSetting sus = (SharedUserSetting) obj;
4800                 return sus.name + ":" + sus.userId;
4801             } else if (obj instanceof PackageSetting) {
4802                 final PackageSetting ps = (PackageSetting) obj;
4803                 return ps.name;
4804             }
4805         }
4806         return null;
4807     }
4808
4809     @Override
4810     public int getUidForSharedUser(String sharedUserName) {
4811         if(sharedUserName == null) {
4812             return -1;
4813         }
4814         // reader
4815         synchronized (mPackages) {
4816             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4817             if (suid == null) {
4818                 return -1;
4819             }
4820             return suid.userId;
4821         }
4822     }
4823
4824     @Override
4825     public int getFlagsForUid(int uid) {
4826         synchronized (mPackages) {
4827             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4828             if (obj instanceof SharedUserSetting) {
4829                 final SharedUserSetting sus = (SharedUserSetting) obj;
4830                 return sus.pkgFlags;
4831             } else if (obj instanceof PackageSetting) {
4832                 final PackageSetting ps = (PackageSetting) obj;
4833                 return ps.pkgFlags;
4834             }
4835         }
4836         return 0;
4837     }
4838
4839     @Override
4840     public int getPrivateFlagsForUid(int uid) {
4841         synchronized (mPackages) {
4842             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4843             if (obj instanceof SharedUserSetting) {
4844                 final SharedUserSetting sus = (SharedUserSetting) obj;
4845                 return sus.pkgPrivateFlags;
4846             } else if (obj instanceof PackageSetting) {
4847                 final PackageSetting ps = (PackageSetting) obj;
4848                 return ps.pkgPrivateFlags;
4849             }
4850         }
4851         return 0;
4852     }
4853
4854     @Override
4855     public boolean isUidPrivileged(int uid) {
4856         uid = UserHandle.getAppId(uid);
4857         // reader
4858         synchronized (mPackages) {
4859             Object obj = mSettings.getUserIdLPr(uid);
4860             if (obj instanceof SharedUserSetting) {
4861                 final SharedUserSetting sus = (SharedUserSetting) obj;
4862                 final Iterator<PackageSetting> it = sus.packages.iterator();
4863                 while (it.hasNext()) {
4864                     if (it.next().isPrivileged()) {
4865                         return true;
4866                     }
4867                 }
4868             } else if (obj instanceof PackageSetting) {
4869                 final PackageSetting ps = (PackageSetting) obj;
4870                 return ps.isPrivileged();
4871             }
4872         }
4873         return false;
4874     }
4875
4876     @Override
4877     public String[] getAppOpPermissionPackages(String permissionName) {
4878         synchronized (mPackages) {
4879             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4880             if (pkgs == null) {
4881                 return null;
4882             }
4883             return pkgs.toArray(new String[pkgs.size()]);
4884         }
4885     }
4886
4887     @Override
4888     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4889             int flags, int userId) {
4890         try {
4891             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
4892
4893             if (!sUserManager.exists(userId)) return null;
4894             flags = updateFlagsForResolve(flags, userId, intent);
4895             enforceCrossUserPermission(Binder.getCallingUid(), userId,
4896                     false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
4897
4898             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
4899             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
4900                     flags, userId);
4901             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4902
4903             final ResolveInfo bestChoice =
4904                     chooseBestActivity(intent, resolvedType, flags, query, userId);
4905             return bestChoice;
4906         } finally {
4907             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4908         }
4909     }
4910
4911     @Override
4912     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4913             IntentFilter filter, int match, ComponentName activity) {
4914         final int userId = UserHandle.getCallingUserId();
4915         if (DEBUG_PREFERRED) {
4916             Log.v(TAG, "setLastChosenActivity intent=" + intent
4917                 + " resolvedType=" + resolvedType
4918                 + " flags=" + flags
4919                 + " filter=" + filter
4920                 + " match=" + match
4921                 + " activity=" + activity);
4922             filter.dump(new PrintStreamPrinter(System.out), "    ");
4923         }
4924         intent.setComponent(null);
4925         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4926                 userId);
4927         // Find any earlier preferred or last chosen entries and nuke them
4928         findPreferredActivity(intent, resolvedType,
4929                 flags, query, 0, false, true, false, userId);
4930         // Add the new activity as the last chosen for this filter
4931         addPreferredActivityInternal(filter, match, null, activity, false, userId,
4932                 "Setting last chosen");
4933     }
4934
4935     @Override
4936     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4937         final int userId = UserHandle.getCallingUserId();
4938         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4939         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4940                 userId);
4941         return findPreferredActivity(intent, resolvedType, flags, query, 0,
4942                 false, false, false, userId);
4943     }
4944
4945     private boolean isEphemeralDisabled() {
4946         // ephemeral apps have been disabled across the board
4947         if (DISABLE_EPHEMERAL_APPS) {
4948             return true;
4949         }
4950         // system isn't up yet; can't read settings, so, assume no ephemeral apps
4951         if (!mSystemReady) {
4952             return true;
4953         }
4954         // we can't get a content resolver until the system is ready; these checks must happen last
4955         final ContentResolver resolver = mContext.getContentResolver();
4956         if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) {
4957             return true;
4958         }
4959         return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0;
4960     }
4961
4962     private boolean isEphemeralAllowed(
4963             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
4964             boolean skipPackageCheck) {
4965         // Short circuit and return early if possible.
4966         if (isEphemeralDisabled()) {
4967             return false;
4968         }
4969         final int callingUser = UserHandle.getCallingUserId();
4970         if (callingUser != UserHandle.USER_SYSTEM) {
4971             return false;
4972         }
4973         if (mEphemeralResolverConnection == null) {
4974             return false;
4975         }
4976         if (intent.getComponent() != null) {
4977             return false;
4978         }
4979         if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
4980             return false;
4981         }
4982         if (!skipPackageCheck && intent.getPackage() != null) {
4983             return false;
4984         }
4985         final boolean isWebUri = hasWebURI(intent);
4986         if (!isWebUri || intent.getData().getHost() == null) {
4987             return false;
4988         }
4989         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4990         synchronized (mPackages) {
4991             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
4992             for (int n = 0; n < count; n++) {
4993                 ResolveInfo info = resolvedActivities.get(n);
4994                 String packageName = info.activityInfo.packageName;
4995                 PackageSetting ps = mSettings.mPackages.get(packageName);
4996                 if (ps != null) {
4997                     // Try to get the status from User settings first
4998                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4999                     int status = (int) (packedStatus >> 32);
5000                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5001                             || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5002                         if (DEBUG_EPHEMERAL) {
5003                             Slog.v(TAG, "DENY ephemeral apps;"
5004                                 + " pkg: " + packageName + ", status: " + status);
5005                         }
5006                         return false;
5007                     }
5008                 }
5009             }
5010         }
5011         // We've exhausted all ways to deny ephemeral application; let the system look for them.
5012         return true;
5013     }
5014
5015     private static EphemeralResolveInfo getEphemeralResolveInfo(
5016             Context context, EphemeralResolverConnection resolverConnection, Intent intent,
5017             String resolvedType, int userId, String packageName) {
5018         final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(),
5019                 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK);
5020         final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(),
5021                 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT);
5022         final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask,
5023                 ephemeralPrefixCount);
5024         final int[] shaPrefix = digest.getDigestPrefix();
5025         final byte[][] digestBytes = digest.getDigestBytes();
5026         final List<EphemeralResolveInfo> ephemeralResolveInfoList =
5027                 resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask);
5028         if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
5029             // No hash prefix match; there are no ephemeral apps for this domain.
5030             return null;
5031         }
5032
5033         // Go in reverse order so we match the narrowest scope first.
5034         for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
5035             for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
5036                 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
5037                     continue;
5038                 }
5039                 final List<IntentFilter> filters = ephemeralApplication.getFilters();
5040                 // No filters; this should never happen.
5041                 if (filters.isEmpty()) {
5042                     continue;
5043                 }
5044                 if (packageName != null
5045                         && !packageName.equals(ephemeralApplication.getPackageName())) {
5046                     continue;
5047                 }
5048                 // We have a domain match; resolve the filters to see if anything matches.
5049                 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
5050                 for (int j = filters.size() - 1; j >= 0; --j) {
5051                     final EphemeralResolveIntentInfo intentInfo =
5052                             new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
5053                     ephemeralResolver.addFilter(intentInfo);
5054                 }
5055                 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
5056                         intent, resolvedType, false /*defaultOnly*/, userId);
5057                 if (!matchedResolveInfoList.isEmpty()) {
5058                     return matchedResolveInfoList.get(0);
5059                 }
5060             }
5061         }
5062         // Hash or filter mis-match; no ephemeral apps for this domain.
5063         return null;
5064     }
5065
5066     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5067             int flags, List<ResolveInfo> query, int userId) {
5068         if (query != null) {
5069             final int N = query.size();
5070             if (N == 1) {
5071                 return query.get(0);
5072             } else if (N > 1) {
5073                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5074                 // If there is more than one activity with the same priority,
5075                 // then let the user decide between them.
5076                 ResolveInfo r0 = query.get(0);
5077                 ResolveInfo r1 = query.get(1);
5078                 if (DEBUG_INTENT_MATCHING || debug) {
5079                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5080                             + r1.activityInfo.name + "=" + r1.priority);
5081                 }
5082                 // If the first activity has a higher priority, or a different
5083                 // default, then it is always desirable to pick it.
5084                 if (r0.priority != r1.priority
5085                         || r0.preferredOrder != r1.preferredOrder
5086                         || r0.isDefault != r1.isDefault) {
5087                     return query.get(0);
5088                 }
5089                 // If we have saved a preference for a preferred activity for
5090                 // this Intent, use that.
5091                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5092                         flags, query, r0.priority, true, false, debug, userId);
5093                 if (ri != null) {
5094                     return ri;
5095                 }
5096                 ri = new ResolveInfo(mResolveInfo);
5097                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
5098                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5099                 // If all of the options come from the same package, show the application's
5100                 // label and icon instead of the generic resolver's.
5101                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5102                 // and then throw away the ResolveInfo itself, meaning that the caller loses
5103                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5104                 // a fallback for this case; we only set the target package's resources on
5105                 // the ResolveInfo, not the ActivityInfo.
5106                 final String intentPackage = intent.getPackage();
5107                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5108                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5109                     ri.resolvePackageName = intentPackage;
5110                     if (userNeedsBadging(userId)) {
5111                         ri.noResourceId = true;
5112                     } else {
5113                         ri.icon = appi.icon;
5114                     }
5115                     ri.iconResourceId = appi.icon;
5116                     ri.labelRes = appi.labelRes;
5117                 }
5118                 ri.activityInfo.applicationInfo = new ApplicationInfo(
5119                         ri.activityInfo.applicationInfo);
5120                 if (userId != 0) {
5121                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5122                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5123                 }
5124                 // Make sure that the resolver is displayable in car mode
5125                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5126                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5127                 return ri;
5128             }
5129         }
5130         return null;
5131     }
5132
5133     /**
5134      * Return true if the given list is not empty and all of its contents have
5135      * an activityInfo with the given package name.
5136      */
5137     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5138         if (ArrayUtils.isEmpty(list)) {
5139             return false;
5140         }
5141         for (int i = 0, N = list.size(); i < N; i++) {
5142             final ResolveInfo ri = list.get(i);
5143             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5144             if (ai == null || !packageName.equals(ai.packageName)) {
5145                 return false;
5146             }
5147         }
5148         return true;
5149     }
5150
5151     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5152             int flags, List<ResolveInfo> query, boolean debug, int userId) {
5153         final int N = query.size();
5154         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5155                 .get(userId);
5156         // Get the list of persistent preferred activities that handle the intent
5157         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5158         List<PersistentPreferredActivity> pprefs = ppir != null
5159                 ? ppir.queryIntent(intent, resolvedType,
5160                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
5161                 : null;
5162         if (pprefs != null && pprefs.size() > 0) {
5163             final int M = pprefs.size();
5164             for (int i=0; i<M; i++) {
5165                 final PersistentPreferredActivity ppa = pprefs.get(i);
5166                 if (DEBUG_PREFERRED || debug) {
5167                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5168                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5169                             + "\n  component=" + ppa.mComponent);
5170                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5171                 }
5172                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5173                         flags | MATCH_DISABLED_COMPONENTS, userId);
5174                 if (DEBUG_PREFERRED || debug) {
5175                     Slog.v(TAG, "Found persistent preferred activity:");
5176                     if (ai != null) {
5177                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5178                     } else {
5179                         Slog.v(TAG, "  null");
5180                     }
5181                 }
5182                 if (ai == null) {
5183                     // This previously registered persistent preferred activity
5184                     // component is no longer known. Ignore it and do NOT remove it.
5185                     continue;
5186                 }
5187                 for (int j=0; j<N; j++) {
5188                     final ResolveInfo ri = query.get(j);
5189                     if (!ri.activityInfo.applicationInfo.packageName
5190                             .equals(ai.applicationInfo.packageName)) {
5191                         continue;
5192                     }
5193                     if (!ri.activityInfo.name.equals(ai.name)) {
5194                         continue;
5195                     }
5196                     //  Found a persistent preference that can handle the intent.
5197                     if (DEBUG_PREFERRED || debug) {
5198                         Slog.v(TAG, "Returning persistent preferred activity: " +
5199                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5200                     }
5201                     return ri;
5202                 }
5203             }
5204         }
5205         return null;
5206     }
5207
5208     // TODO: handle preferred activities missing while user has amnesia
5209     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5210             List<ResolveInfo> query, int priority, boolean always,
5211             boolean removeMatches, boolean debug, int userId) {
5212         if (!sUserManager.exists(userId)) return null;
5213         flags = updateFlagsForResolve(flags, userId, intent);
5214         // writer
5215         synchronized (mPackages) {
5216             if (intent.getSelector() != null) {
5217                 intent = intent.getSelector();
5218             }
5219             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
5220
5221             // Try to find a matching persistent preferred activity.
5222             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5223                     debug, userId);
5224
5225             // If a persistent preferred activity matched, use it.
5226             if (pri != null) {
5227                 return pri;
5228             }
5229
5230             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5231             // Get the list of preferred activities that handle the intent
5232             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5233             List<PreferredActivity> prefs = pir != null
5234                     ? pir.queryIntent(intent, resolvedType,
5235                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
5236                     : null;
5237             if (prefs != null && prefs.size() > 0) {
5238                 boolean changed = false;
5239                 try {
5240                     // First figure out how good the original match set is.
5241                     // We will only allow preferred activities that came
5242                     // from the same match quality.
5243                     int match = 0;
5244
5245                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5246
5247                     final int N = query.size();
5248                     for (int j=0; j<N; j++) {
5249                         final ResolveInfo ri = query.get(j);
5250                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5251                                 + ": 0x" + Integer.toHexString(match));
5252                         if (ri.match > match) {
5253                             match = ri.match;
5254                         }
5255                     }
5256
5257                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5258                             + Integer.toHexString(match));
5259
5260                     match &= IntentFilter.MATCH_CATEGORY_MASK;
5261                     final int M = prefs.size();
5262                     for (int i=0; i<M; i++) {
5263                         final PreferredActivity pa = prefs.get(i);
5264                         if (DEBUG_PREFERRED || debug) {
5265                             Slog.v(TAG, "Checking PreferredActivity ds="
5266                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
5267                                     + "\n  component=" + pa.mPref.mComponent);
5268                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5269                         }
5270                         if (pa.mPref.mMatch != match) {
5271                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
5272                                     + Integer.toHexString(pa.mPref.mMatch));
5273                             continue;
5274                         }
5275                         // If it's not an "always" type preferred activity and that's what we're
5276                         // looking for, skip it.
5277                         if (always && !pa.mPref.mAlways) {
5278                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
5279                             continue;
5280                         }
5281                         final ActivityInfo ai = getActivityInfo(
5282                                 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
5283                                         | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
5284                                 userId);
5285                         if (DEBUG_PREFERRED || debug) {
5286                             Slog.v(TAG, "Found preferred activity:");
5287                             if (ai != null) {
5288                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5289                             } else {
5290                                 Slog.v(TAG, "  null");
5291                             }
5292                         }
5293                         if (ai == null) {
5294                             // This previously registered preferred activity
5295                             // component is no longer known.  Most likely an update
5296                             // to the app was installed and in the new version this
5297                             // component no longer exists.  Clean it up by removing
5298                             // it from the preferred activities list, and skip it.
5299                             Slog.w(TAG, "Removing dangling preferred activity: "
5300                                     + pa.mPref.mComponent);
5301                             pir.removeFilter(pa);
5302                             changed = true;
5303                             continue;
5304                         }
5305                         for (int j=0; j<N; j++) {
5306                             final ResolveInfo ri = query.get(j);
5307                             if (!ri.activityInfo.applicationInfo.packageName
5308                                     .equals(ai.applicationInfo.packageName)) {
5309                                 continue;
5310                             }
5311                             if (!ri.activityInfo.name.equals(ai.name)) {
5312                                 continue;
5313                             }
5314
5315                             if (removeMatches) {
5316                                 pir.removeFilter(pa);
5317                                 changed = true;
5318                                 if (DEBUG_PREFERRED) {
5319                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
5320                                 }
5321                                 break;
5322                             }
5323
5324                             // Okay we found a previously set preferred or last chosen app.
5325                             // If the result set is different from when this
5326                             // was created, we need to clear it and re-ask the
5327                             // user their preference, if we're looking for an "always" type entry.
5328                             if (always && !pa.mPref.sameSet(query)) {
5329                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
5330                                         + intent + " type " + resolvedType);
5331                                 if (DEBUG_PREFERRED) {
5332                                     Slog.v(TAG, "Removing preferred activity since set changed "
5333                                             + pa.mPref.mComponent);
5334                                 }
5335                                 pir.removeFilter(pa);
5336                                 // Re-add the filter as a "last chosen" entry (!always)
5337                                 PreferredActivity lastChosen = new PreferredActivity(
5338                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
5339                                 pir.addFilter(lastChosen);
5340                                 changed = true;
5341                                 return null;
5342                             }
5343
5344                             // Yay! Either the set matched or we're looking for the last chosen
5345                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
5346                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5347                             return ri;
5348                         }
5349                     }
5350                 } finally {
5351                     if (changed) {
5352                         if (DEBUG_PREFERRED) {
5353                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
5354                         }
5355                         scheduleWritePackageRestrictionsLocked(userId);
5356                     }
5357                 }
5358             }
5359         }
5360         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
5361         return null;
5362     }
5363
5364     /*
5365      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
5366      */
5367     @Override
5368     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
5369             int targetUserId) {
5370         mContext.enforceCallingOrSelfPermission(
5371                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
5372         List<CrossProfileIntentFilter> matches =
5373                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
5374         if (matches != null) {
5375             int size = matches.size();
5376             for (int i = 0; i < size; i++) {
5377                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
5378             }
5379         }
5380         if (hasWebURI(intent)) {
5381             // cross-profile app linking works only towards the parent.
5382             final UserInfo parent = getProfileParent(sourceUserId);
5383             synchronized(mPackages) {
5384                 int flags = updateFlagsForResolve(0, parent.id, intent);
5385                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
5386                         intent, resolvedType, flags, sourceUserId, parent.id);
5387                 return xpDomainInfo != null;
5388             }
5389         }
5390         return false;
5391     }
5392
5393     private UserInfo getProfileParent(int userId) {
5394         final long identity = Binder.clearCallingIdentity();
5395         try {
5396             return sUserManager.getProfileParent(userId);
5397         } finally {
5398             Binder.restoreCallingIdentity(identity);
5399         }
5400     }
5401
5402     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
5403             String resolvedType, int userId) {
5404         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
5405         if (resolver != null) {
5406             return resolver.queryIntent(intent, resolvedType, false, userId);
5407         }
5408         return null;
5409     }
5410
5411     @Override
5412     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
5413             String resolvedType, int flags, int userId) {
5414         try {
5415             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5416
5417             return new ParceledListSlice<>(
5418                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
5419         } finally {
5420             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5421         }
5422     }
5423
5424     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5425             String resolvedType, int flags, int userId) {
5426         if (!sUserManager.exists(userId)) return Collections.emptyList();
5427         flags = updateFlagsForResolve(flags, userId, intent);
5428         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5429                 false /* requireFullPermission */, false /* checkShell */,
5430                 "query intent activities");
5431         ComponentName comp = intent.getComponent();
5432         if (comp == null) {
5433             if (intent.getSelector() != null) {
5434                 intent = intent.getSelector();
5435                 comp = intent.getComponent();
5436             }
5437         }
5438
5439         if (comp != null) {
5440             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5441             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
5442             if (ai != null) {
5443                 final ResolveInfo ri = new ResolveInfo();
5444                 ri.activityInfo = ai;
5445                 list.add(ri);
5446             }
5447             return list;
5448         }
5449
5450         // reader
5451         boolean sortResult = false;
5452         boolean addEphemeral = false;
5453         boolean matchEphemeralPackage = false;
5454         List<ResolveInfo> result;
5455         final String pkgName = intent.getPackage();
5456         synchronized (mPackages) {
5457             if (pkgName == null) {
5458                 List<CrossProfileIntentFilter> matchingFilters =
5459                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
5460                 // Check for results that need to skip the current profile.
5461                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
5462                         resolvedType, flags, userId);
5463                 if (xpResolveInfo != null) {
5464                     List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
5465                     xpResult.add(xpResolveInfo);
5466                     return filterIfNotSystemUser(xpResult, userId);
5467                 }
5468
5469                 // Check for results in the current profile.
5470                 result = filterIfNotSystemUser(mActivities.queryIntent(
5471                         intent, resolvedType, flags, userId), userId);
5472                 addEphemeral =
5473                         isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
5474
5475                 // Check for cross profile results.
5476                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
5477                 xpResolveInfo = queryCrossProfileIntents(
5478                         matchingFilters, intent, resolvedType, flags, userId,
5479                         hasNonNegativePriorityResult);
5480                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
5481                     boolean isVisibleToUser = filterIfNotSystemUser(
5482                             Collections.singletonList(xpResolveInfo), userId).size() > 0;
5483                     if (isVisibleToUser) {
5484                         result.add(xpResolveInfo);
5485                         sortResult = true;
5486                     }
5487                 }
5488                 if (hasWebURI(intent)) {
5489                     CrossProfileDomainInfo xpDomainInfo = null;
5490                     final UserInfo parent = getProfileParent(userId);
5491                     if (parent != null) {
5492                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
5493                                 flags, userId, parent.id);
5494                     }
5495                     if (xpDomainInfo != null) {
5496                         if (xpResolveInfo != null) {
5497                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
5498                             // in the result.
5499                             result.remove(xpResolveInfo);
5500                         }
5501                         if (result.size() == 0 && !addEphemeral) {
5502                             result.add(xpDomainInfo.resolveInfo);
5503                             return result;
5504                         }
5505                     }
5506                     if (result.size() > 1 || addEphemeral) {
5507                         result = filterCandidatesWithDomainPreferredActivitiesLPr(
5508                                 intent, flags, result, xpDomainInfo, userId);
5509                         sortResult = true;
5510                     }
5511                 }
5512             } else {
5513                 final PackageParser.Package pkg = mPackages.get(pkgName);
5514                 if (pkg != null) {
5515                     result = filterIfNotSystemUser(
5516                             mActivities.queryIntentForPackage(
5517                                     intent, resolvedType, flags, pkg.activities, userId),
5518                             userId);
5519                 } else {
5520                     // the caller wants to resolve for a particular package; however, there
5521                     // were no installed results, so, try to find an ephemeral result
5522                     addEphemeral = isEphemeralAllowed(
5523                             intent, null /*result*/, userId, true /*skipPackageCheck*/);
5524                     matchEphemeralPackage = true;
5525                     result = new ArrayList<ResolveInfo>();
5526                 }
5527             }
5528         }
5529         if (addEphemeral) {
5530             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
5531             final EphemeralResolveInfo ai = getEphemeralResolveInfo(
5532                     mContext, mEphemeralResolverConnection, intent, resolvedType, userId,
5533                     matchEphemeralPackage ? pkgName : null);
5534             if (ai != null) {
5535                 if (DEBUG_EPHEMERAL) {
5536                     Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
5537                 }
5538                 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
5539                 ephemeralInstaller.ephemeralResolveInfo = ai;
5540                 // make sure this resolver is the default
5541                 ephemeralInstaller.isDefault = true;
5542                 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
5543                         | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
5544                 // add a non-generic filter
5545                 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
5546                 ephemeralInstaller.filter.addDataPath(
5547                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
5548                 result.add(ephemeralInstaller);
5549             }
5550             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5551         }
5552         if (sortResult) {
5553             Collections.sort(result, mResolvePrioritySorter);
5554         }
5555         return result;
5556     }
5557
5558     private static class CrossProfileDomainInfo {
5559         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
5560         ResolveInfo resolveInfo;
5561         /* Best domain verification status of the activities found in the other profile */
5562         int bestDomainVerificationStatus;
5563     }
5564
5565     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5566             String resolvedType, int flags, int sourceUserId, int parentUserId) {
5567         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
5568                 sourceUserId)) {
5569             return null;
5570         }
5571         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5572                 resolvedType, flags, parentUserId);
5573
5574         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
5575             return null;
5576         }
5577         CrossProfileDomainInfo result = null;
5578         int size = resultTargetUser.size();
5579         for (int i = 0; i < size; i++) {
5580             ResolveInfo riTargetUser = resultTargetUser.get(i);
5581             // Intent filter verification is only for filters that specify a host. So don't return
5582             // those that handle all web uris.
5583             if (riTargetUser.handleAllWebDataURI) {
5584                 continue;
5585             }
5586             String packageName = riTargetUser.activityInfo.packageName;
5587             PackageSetting ps = mSettings.mPackages.get(packageName);
5588             if (ps == null) {
5589                 continue;
5590             }
5591             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
5592             int status = (int)(verificationState >> 32);
5593             if (result == null) {
5594                 result = new CrossProfileDomainInfo();
5595                 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5596                         sourceUserId, parentUserId);
5597                 result.bestDomainVerificationStatus = status;
5598             } else {
5599                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5600                         result.bestDomainVerificationStatus);
5601             }
5602         }
5603         // Don't consider matches with status NEVER across profiles.
5604         if (result != null && result.bestDomainVerificationStatus
5605                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5606             return null;
5607         }
5608         return result;
5609     }
5610
5611     /**
5612      * Verification statuses are ordered from the worse to the best, except for
5613      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5614      */
5615     private int bestDomainVerificationStatus(int status1, int status2) {
5616         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5617             return status2;
5618         }
5619         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5620             return status1;
5621         }
5622         return (int) MathUtils.max(status1, status2);
5623     }
5624
5625     private boolean isUserEnabled(int userId) {
5626         long callingId = Binder.clearCallingIdentity();
5627         try {
5628             UserInfo userInfo = sUserManager.getUserInfo(userId);
5629             return userInfo != null && userInfo.isEnabled();
5630         } finally {
5631             Binder.restoreCallingIdentity(callingId);
5632         }
5633     }
5634
5635     /**
5636      * Filter out activities with systemUserOnly flag set, when current user is not System.
5637      *
5638      * @return filtered list
5639      */
5640     private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5641         if (userId == UserHandle.USER_SYSTEM) {
5642             return resolveInfos;
5643         }
5644         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5645             ResolveInfo info = resolveInfos.get(i);
5646             if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5647                 resolveInfos.remove(i);
5648             }
5649         }
5650         return resolveInfos;
5651     }
5652
5653     /**
5654      * @param resolveInfos list of resolve infos in descending priority order
5655      * @return if the list contains a resolve info with non-negative priority
5656      */
5657     private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5658         return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5659     }
5660
5661     private static boolean hasWebURI(Intent intent) {
5662         if (intent.getData() == null) {
5663             return false;
5664         }
5665         final String scheme = intent.getScheme();
5666         if (TextUtils.isEmpty(scheme)) {
5667             return false;
5668         }
5669         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5670     }
5671
5672     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5673             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5674             int userId) {
5675         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5676
5677         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5678             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5679                     candidates.size());
5680         }
5681
5682         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5683         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5684         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5685         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5686         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5687         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5688
5689         synchronized (mPackages) {
5690             final int count = candidates.size();
5691             // First, try to use linked apps. Partition the candidates into four lists:
5692             // one for the final results, one for the "do not use ever", one for "undefined status"
5693             // and finally one for "browser app type".
5694             for (int n=0; n<count; n++) {
5695                 ResolveInfo info = candidates.get(n);
5696                 String packageName = info.activityInfo.packageName;
5697                 PackageSetting ps = mSettings.mPackages.get(packageName);
5698                 if (ps != null) {
5699                     // Add to the special match all list (Browser use case)
5700                     if (info.handleAllWebDataURI) {
5701                         matchAllList.add(info);
5702                         continue;
5703                     }
5704                     // Try to get the status from User settings first
5705                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5706                     int status = (int)(packedStatus >> 32);
5707                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5708                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5709                         if (DEBUG_DOMAIN_VERIFICATION) {
5710                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5711                                     + " : linkgen=" + linkGeneration);
5712                         }
5713                         // Use link-enabled generation as preferredOrder, i.e.
5714                         // prefer newly-enabled over earlier-enabled.
5715                         info.preferredOrder = linkGeneration;
5716                         alwaysList.add(info);
5717                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5718                         if (DEBUG_DOMAIN_VERIFICATION) {
5719                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5720                         }
5721                         neverList.add(info);
5722                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5723                         if (DEBUG_DOMAIN_VERIFICATION) {
5724                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5725                         }
5726                         alwaysAskList.add(info);
5727                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5728                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5729                         if (DEBUG_DOMAIN_VERIFICATION) {
5730                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5731                         }
5732                         undefinedList.add(info);
5733                     }
5734                 }
5735             }
5736
5737             // We'll want to include browser possibilities in a few cases
5738             boolean includeBrowser = false;
5739
5740             // First try to add the "always" resolution(s) for the current user, if any
5741             if (alwaysList.size() > 0) {
5742                 result.addAll(alwaysList);
5743             } else {
5744                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
5745                 result.addAll(undefinedList);
5746                 // Maybe add one for the other profile.
5747                 if (xpDomainInfo != null && (
5748                         xpDomainInfo.bestDomainVerificationStatus
5749                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5750                     result.add(xpDomainInfo.resolveInfo);
5751                 }
5752                 includeBrowser = true;
5753             }
5754
5755             // The presence of any 'always ask' alternatives means we'll also offer browsers.
5756             // If there were 'always' entries their preferred order has been set, so we also
5757             // back that off to make the alternatives equivalent
5758             if (alwaysAskList.size() > 0) {
5759                 for (ResolveInfo i : result) {
5760                     i.preferredOrder = 0;
5761                 }
5762                 result.addAll(alwaysAskList);
5763                 includeBrowser = true;
5764             }
5765
5766             if (includeBrowser) {
5767                 // Also add browsers (all of them or only the default one)
5768                 if (DEBUG_DOMAIN_VERIFICATION) {
5769                     Slog.v(TAG, "   ...including browsers in candidate set");
5770                 }
5771                 if ((matchFlags & MATCH_ALL) != 0) {
5772                     result.addAll(matchAllList);
5773                 } else {
5774                     // Browser/generic handling case.  If there's a default browser, go straight
5775                     // to that (but only if there is no other higher-priority match).
5776                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5777                     int maxMatchPrio = 0;
5778                     ResolveInfo defaultBrowserMatch = null;
5779                     final int numCandidates = matchAllList.size();
5780                     for (int n = 0; n < numCandidates; n++) {
5781                         ResolveInfo info = matchAllList.get(n);
5782                         // track the highest overall match priority...
5783                         if (info.priority > maxMatchPrio) {
5784                             maxMatchPrio = info.priority;
5785                         }
5786                         // ...and the highest-priority default browser match
5787                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5788                             if (defaultBrowserMatch == null
5789                                     || (defaultBrowserMatch.priority < info.priority)) {
5790                                 if (debug) {
5791                                     Slog.v(TAG, "Considering default browser match " + info);
5792                                 }
5793                                 defaultBrowserMatch = info;
5794                             }
5795                         }
5796                     }
5797                     if (defaultBrowserMatch != null
5798                             && defaultBrowserMatch.priority >= maxMatchPrio
5799                             && !TextUtils.isEmpty(defaultBrowserPackageName))
5800                     {
5801                         if (debug) {
5802                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5803                         }
5804                         result.add(defaultBrowserMatch);
5805                     } else {
5806                         result.addAll(matchAllList);
5807                     }
5808                 }
5809
5810                 // If there is nothing selected, add all candidates and remove the ones that the user
5811                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5812                 if (result.size() == 0) {
5813                     result.addAll(candidates);
5814                     result.removeAll(neverList);
5815                 }
5816             }
5817         }
5818         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5819             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5820                     result.size());
5821             for (ResolveInfo info : result) {
5822                 Slog.v(TAG, "  + " + info.activityInfo);
5823             }
5824         }
5825         return result;
5826     }
5827
5828     // Returns a packed value as a long:
5829     //
5830     // high 'int'-sized word: link status: undefined/ask/never/always.
5831     // low 'int'-sized word: relative priority among 'always' results.
5832     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5833         long result = ps.getDomainVerificationStatusForUser(userId);
5834         // if none available, get the master status
5835         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5836             if (ps.getIntentFilterVerificationInfo() != null) {
5837                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5838             }
5839         }
5840         return result;
5841     }
5842
5843     private ResolveInfo querySkipCurrentProfileIntents(
5844             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5845             int flags, int sourceUserId) {
5846         if (matchingFilters != null) {
5847             int size = matchingFilters.size();
5848             for (int i = 0; i < size; i ++) {
5849                 CrossProfileIntentFilter filter = matchingFilters.get(i);
5850                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5851                     // Checking if there are activities in the target user that can handle the
5852                     // intent.
5853                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5854                             resolvedType, flags, sourceUserId);
5855                     if (resolveInfo != null) {
5856                         return resolveInfo;
5857                     }
5858                 }
5859             }
5860         }
5861         return null;
5862     }
5863
5864     // Return matching ResolveInfo in target user if any.
5865     private ResolveInfo queryCrossProfileIntents(
5866             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5867             int flags, int sourceUserId, boolean matchInCurrentProfile) {
5868         if (matchingFilters != null) {
5869             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5870             // match the same intent. For performance reasons, it is better not to
5871             // run queryIntent twice for the same userId
5872             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5873             int size = matchingFilters.size();
5874             for (int i = 0; i < size; i++) {
5875                 CrossProfileIntentFilter filter = matchingFilters.get(i);
5876                 int targetUserId = filter.getTargetUserId();
5877                 boolean skipCurrentProfile =
5878                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5879                 boolean skipCurrentProfileIfNoMatchFound =
5880                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5881                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5882                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5883                     // Checking if there are activities in the target user that can handle the
5884                     // intent.
5885                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5886                             resolvedType, flags, sourceUserId);
5887                     if (resolveInfo != null) return resolveInfo;
5888                     alreadyTriedUserIds.put(targetUserId, true);
5889                 }
5890             }
5891         }
5892         return null;
5893     }
5894
5895     /**
5896      * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5897      * will forward the intent to the filter's target user.
5898      * Otherwise, returns null.
5899      */
5900     private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5901             String resolvedType, int flags, int sourceUserId) {
5902         int targetUserId = filter.getTargetUserId();
5903         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5904                 resolvedType, flags, targetUserId);
5905         if (resultTargetUser != null && isUserEnabled(targetUserId)) {
5906             // If all the matches in the target profile are suspended, return null.
5907             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
5908                 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
5909                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
5910                     return createForwardingResolveInfoUnchecked(filter, sourceUserId,
5911                             targetUserId);
5912                 }
5913             }
5914         }
5915         return null;
5916     }
5917
5918     private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5919             int sourceUserId, int targetUserId) {
5920         ResolveInfo forwardingResolveInfo = new ResolveInfo();
5921         long ident = Binder.clearCallingIdentity();
5922         boolean targetIsProfile;
5923         try {
5924             targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5925         } finally {
5926             Binder.restoreCallingIdentity(ident);
5927         }
5928         String className;
5929         if (targetIsProfile) {
5930             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5931         } else {
5932             className = FORWARD_INTENT_TO_PARENT;
5933         }
5934         ComponentName forwardingActivityComponentName = new ComponentName(
5935                 mAndroidApplication.packageName, className);
5936         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5937                 sourceUserId);
5938         if (!targetIsProfile) {
5939             forwardingActivityInfo.showUserIcon = targetUserId;
5940             forwardingResolveInfo.noResourceId = true;
5941         }
5942         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5943         forwardingResolveInfo.priority = 0;
5944         forwardingResolveInfo.preferredOrder = 0;
5945         forwardingResolveInfo.match = 0;
5946         forwardingResolveInfo.isDefault = true;
5947         forwardingResolveInfo.filter = filter;
5948         forwardingResolveInfo.targetUserId = targetUserId;
5949         return forwardingResolveInfo;
5950     }
5951
5952     @Override
5953     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5954             Intent[] specifics, String[] specificTypes, Intent intent,
5955             String resolvedType, int flags, int userId) {
5956         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
5957                 specificTypes, intent, resolvedType, flags, userId));
5958     }
5959
5960     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
5961             Intent[] specifics, String[] specificTypes, Intent intent,
5962             String resolvedType, int flags, int userId) {
5963         if (!sUserManager.exists(userId)) return Collections.emptyList();
5964         flags = updateFlagsForResolve(flags, userId, intent);
5965         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5966                 false /* requireFullPermission */, false /* checkShell */,
5967                 "query intent activity options");
5968         final String resultsAction = intent.getAction();
5969
5970         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
5971                 | PackageManager.GET_RESOLVED_FILTER, userId);
5972
5973         if (DEBUG_INTENT_MATCHING) {
5974             Log.v(TAG, "Query " + intent + ": " + results);
5975         }
5976
5977         int specificsPos = 0;
5978         int N;
5979
5980         // todo: note that the algorithm used here is O(N^2).  This
5981         // isn't a problem in our current environment, but if we start running
5982         // into situations where we have more than 5 or 10 matches then this
5983         // should probably be changed to something smarter...
5984
5985         // First we go through and resolve each of the specific items
5986         // that were supplied, taking care of removing any corresponding
5987         // duplicate items in the generic resolve list.
5988         if (specifics != null) {
5989             for (int i=0; i<specifics.length; i++) {
5990                 final Intent sintent = specifics[i];
5991                 if (sintent == null) {
5992                     continue;
5993                 }
5994
5995                 if (DEBUG_INTENT_MATCHING) {
5996                     Log.v(TAG, "Specific #" + i + ": " + sintent);
5997                 }
5998
5999                 String action = sintent.getAction();
6000                 if (resultsAction != null && resultsAction.equals(action)) {
6001                     // If this action was explicitly requested, then don't
6002                     // remove things that have it.
6003                     action = null;
6004                 }
6005
6006                 ResolveInfo ri = null;
6007                 ActivityInfo ai = null;
6008
6009                 ComponentName comp = sintent.getComponent();
6010                 if (comp == null) {
6011                     ri = resolveIntent(
6012                         sintent,
6013                         specificTypes != null ? specificTypes[i] : null,
6014                             flags, userId);
6015                     if (ri == null) {
6016                         continue;
6017                     }
6018                     if (ri == mResolveInfo) {
6019                         // ACK!  Must do something better with this.
6020                     }
6021                     ai = ri.activityInfo;
6022                     comp = new ComponentName(ai.applicationInfo.packageName,
6023                             ai.name);
6024                 } else {
6025                     ai = getActivityInfo(comp, flags, userId);
6026                     if (ai == null) {
6027                         continue;
6028                     }
6029                 }
6030
6031                 // Look for any generic query activities that are duplicates
6032                 // of this specific one, and remove them from the results.
6033                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6034                 N = results.size();
6035                 int j;
6036                 for (j=specificsPos; j<N; j++) {
6037                     ResolveInfo sri = results.get(j);
6038                     if ((sri.activityInfo.name.equals(comp.getClassName())
6039                             && sri.activityInfo.applicationInfo.packageName.equals(
6040                                     comp.getPackageName()))
6041                         || (action != null && sri.filter.matchAction(action))) {
6042                         results.remove(j);
6043                         if (DEBUG_INTENT_MATCHING) Log.v(
6044                             TAG, "Removing duplicate item from " + j
6045                             + " due to specific " + specificsPos);
6046                         if (ri == null) {
6047                             ri = sri;
6048                         }
6049                         j--;
6050                         N--;
6051                     }
6052                 }
6053
6054                 // Add this specific item to its proper place.
6055                 if (ri == null) {
6056                     ri = new ResolveInfo();
6057                     ri.activityInfo = ai;
6058                 }
6059                 results.add(specificsPos, ri);
6060                 ri.specificIndex = i;
6061                 specificsPos++;
6062             }
6063         }
6064
6065         // Now we go through the remaining generic results and remove any
6066         // duplicate actions that are found here.
6067         N = results.size();
6068         for (int i=specificsPos; i<N-1; i++) {
6069             final ResolveInfo rii = results.get(i);
6070             if (rii.filter == null) {
6071                 continue;
6072             }
6073
6074             // Iterate over all of the actions of this result's intent
6075             // filter...  typically this should be just one.
6076             final Iterator<String> it = rii.filter.actionsIterator();
6077             if (it == null) {
6078                 continue;
6079             }
6080             while (it.hasNext()) {
6081                 final String action = it.next();
6082                 if (resultsAction != null && resultsAction.equals(action)) {
6083                     // If this action was explicitly requested, then don't
6084                     // remove things that have it.
6085                     continue;
6086                 }
6087                 for (int j=i+1; j<N; j++) {
6088                     final ResolveInfo rij = results.get(j);
6089                     if (rij.filter != null && rij.filter.hasAction(action)) {
6090                         results.remove(j);
6091                         if (DEBUG_INTENT_MATCHING) Log.v(
6092                             TAG, "Removing duplicate item from " + j
6093                             + " due to action " + action + " at " + i);
6094                         j--;
6095                         N--;
6096                     }
6097                 }
6098             }
6099
6100             // If the caller didn't request filter information, drop it now
6101             // so we don't have to marshall/unmarshall it.
6102             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6103                 rii.filter = null;
6104             }
6105         }
6106
6107         // Filter out the caller activity if so requested.
6108         if (caller != null) {
6109             N = results.size();
6110             for (int i=0; i<N; i++) {
6111                 ActivityInfo ainfo = results.get(i).activityInfo;
6112                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6113                         && caller.getClassName().equals(ainfo.name)) {
6114                     results.remove(i);
6115                     break;
6116                 }
6117             }
6118         }
6119
6120         // If the caller didn't request filter information,
6121         // drop them now so we don't have to
6122         // marshall/unmarshall it.
6123         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6124             N = results.size();
6125             for (int i=0; i<N; i++) {
6126                 results.get(i).filter = null;
6127             }
6128         }
6129
6130         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
6131         return results;
6132     }
6133
6134     @Override
6135     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
6136             String resolvedType, int flags, int userId) {
6137         return new ParceledListSlice<>(
6138                 queryIntentReceiversInternal(intent, resolvedType, flags, userId));
6139     }
6140
6141     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
6142             String resolvedType, int flags, int userId) {
6143         if (!sUserManager.exists(userId)) return Collections.emptyList();
6144         flags = updateFlagsForResolve(flags, userId, intent);
6145         ComponentName comp = intent.getComponent();
6146         if (comp == null) {
6147             if (intent.getSelector() != null) {
6148                 intent = intent.getSelector();
6149                 comp = intent.getComponent();
6150             }
6151         }
6152         if (comp != null) {
6153             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6154             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
6155             if (ai != null) {
6156                 ResolveInfo ri = new ResolveInfo();
6157                 ri.activityInfo = ai;
6158                 list.add(ri);
6159             }
6160             return list;
6161         }
6162
6163         // reader
6164         synchronized (mPackages) {
6165             String pkgName = intent.getPackage();
6166             if (pkgName == null) {
6167                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
6168             }
6169             final PackageParser.Package pkg = mPackages.get(pkgName);
6170             if (pkg != null) {
6171                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
6172                         userId);
6173             }
6174             return Collections.emptyList();
6175         }
6176     }
6177
6178     @Override
6179     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
6180         if (!sUserManager.exists(userId)) return null;
6181         flags = updateFlagsForResolve(flags, userId, intent);
6182         List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
6183         if (query != null) {
6184             if (query.size() >= 1) {
6185                 // If there is more than one service with the same priority,
6186                 // just arbitrarily pick the first one.
6187                 return query.get(0);
6188             }
6189         }
6190         return null;
6191     }
6192
6193     @Override
6194     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
6195             String resolvedType, int flags, int userId) {
6196         return new ParceledListSlice<>(
6197                 queryIntentServicesInternal(intent, resolvedType, flags, userId));
6198     }
6199
6200     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
6201             String resolvedType, int flags, int userId) {
6202         if (!sUserManager.exists(userId)) return Collections.emptyList();
6203         flags = updateFlagsForResolve(flags, userId, intent);
6204         ComponentName comp = intent.getComponent();
6205         if (comp == null) {
6206             if (intent.getSelector() != null) {
6207                 intent = intent.getSelector();
6208                 comp = intent.getComponent();
6209             }
6210         }
6211         if (comp != null) {
6212             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6213             final ServiceInfo si = getServiceInfo(comp, flags, userId);
6214             if (si != null) {
6215                 final ResolveInfo ri = new ResolveInfo();
6216                 ri.serviceInfo = si;
6217                 list.add(ri);
6218             }
6219             return list;
6220         }
6221
6222         // reader
6223         synchronized (mPackages) {
6224             String pkgName = intent.getPackage();
6225             if (pkgName == null) {
6226                 return mServices.queryIntent(intent, resolvedType, flags, userId);
6227             }
6228             final PackageParser.Package pkg = mPackages.get(pkgName);
6229             if (pkg != null) {
6230                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
6231                         userId);
6232             }
6233             return Collections.emptyList();
6234         }
6235     }
6236
6237     @Override
6238     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
6239             String resolvedType, int flags, int userId) {
6240         return new ParceledListSlice<>(
6241                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
6242     }
6243
6244     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
6245             Intent intent, String resolvedType, int flags, int userId) {
6246         if (!sUserManager.exists(userId)) return Collections.emptyList();
6247         flags = updateFlagsForResolve(flags, userId, intent);
6248         ComponentName comp = intent.getComponent();
6249         if (comp == null) {
6250             if (intent.getSelector() != null) {
6251                 intent = intent.getSelector();
6252                 comp = intent.getComponent();
6253             }
6254         }
6255         if (comp != null) {
6256             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6257             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
6258             if (pi != null) {
6259                 final ResolveInfo ri = new ResolveInfo();
6260                 ri.providerInfo = pi;
6261                 list.add(ri);
6262             }
6263             return list;
6264         }
6265
6266         // reader
6267         synchronized (mPackages) {
6268             String pkgName = intent.getPackage();
6269             if (pkgName == null) {
6270                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
6271             }
6272             final PackageParser.Package pkg = mPackages.get(pkgName);
6273             if (pkg != null) {
6274                 return mProviders.queryIntentForPackage(
6275                         intent, resolvedType, flags, pkg.providers, userId);
6276             }
6277             return Collections.emptyList();
6278         }
6279     }
6280
6281     @Override
6282     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
6283         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6284         flags = updateFlagsForPackage(flags, userId, null);
6285         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6286         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6287                 false /* requireFullPermission */, false /* checkShell */,
6288                 "get installed packages");
6289
6290         // writer
6291         synchronized (mPackages) {
6292             ArrayList<PackageInfo> list;
6293             if (listUninstalled) {
6294                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
6295                 for (PackageSetting ps : mSettings.mPackages.values()) {
6296                     final PackageInfo pi;
6297                     if (ps.pkg != null) {
6298                         pi = generatePackageInfo(ps, flags, userId);
6299                     } else {
6300                         pi = generatePackageInfo(ps, flags, userId);
6301                     }
6302                     if (pi != null) {
6303                         list.add(pi);
6304                     }
6305                 }
6306             } else {
6307                 list = new ArrayList<PackageInfo>(mPackages.size());
6308                 for (PackageParser.Package p : mPackages.values()) {
6309                     final PackageInfo pi =
6310                             generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
6311                     if (pi != null) {
6312                         list.add(pi);
6313                     }
6314                 }
6315             }
6316
6317             return new ParceledListSlice<PackageInfo>(list);
6318         }
6319     }
6320
6321     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
6322             String[] permissions, boolean[] tmp, int flags, int userId) {
6323         int numMatch = 0;
6324         final PermissionsState permissionsState = ps.getPermissionsState();
6325         for (int i=0; i<permissions.length; i++) {
6326             final String permission = permissions[i];
6327             if (permissionsState.hasPermission(permission, userId)) {
6328                 tmp[i] = true;
6329                 numMatch++;
6330             } else {
6331                 tmp[i] = false;
6332             }
6333         }
6334         if (numMatch == 0) {
6335             return;
6336         }
6337         final PackageInfo pi;
6338         if (ps.pkg != null) {
6339             pi = generatePackageInfo(ps, flags, userId);
6340         } else {
6341             pi = generatePackageInfo(ps, flags, userId);
6342         }
6343         // The above might return null in cases of uninstalled apps or install-state
6344         // skew across users/profiles.
6345         if (pi != null) {
6346             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
6347                 if (numMatch == permissions.length) {
6348                     pi.requestedPermissions = permissions;
6349                 } else {
6350                     pi.requestedPermissions = new String[numMatch];
6351                     numMatch = 0;
6352                     for (int i=0; i<permissions.length; i++) {
6353                         if (tmp[i]) {
6354                             pi.requestedPermissions[numMatch] = permissions[i];
6355                             numMatch++;
6356                         }
6357                     }
6358                 }
6359             }
6360             list.add(pi);
6361         }
6362     }
6363
6364     @Override
6365     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
6366             String[] permissions, int flags, int userId) {
6367         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6368         flags = updateFlagsForPackage(flags, userId, permissions);
6369         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6370
6371         // writer
6372         synchronized (mPackages) {
6373             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
6374             boolean[] tmpBools = new boolean[permissions.length];
6375             if (listUninstalled) {
6376                 for (PackageSetting ps : mSettings.mPackages.values()) {
6377                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
6378                 }
6379             } else {
6380                 for (PackageParser.Package pkg : mPackages.values()) {
6381                     PackageSetting ps = (PackageSetting)pkg.mExtras;
6382                     if (ps != null) {
6383                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
6384                                 userId);
6385                     }
6386                 }
6387             }
6388
6389             return new ParceledListSlice<PackageInfo>(list);
6390         }
6391     }
6392
6393     @Override
6394     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
6395         final int callingUid = Binder.getCallingUid();
6396         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6397         flags = updateFlagsForApplication(flags, userId, null);
6398         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6399
6400         enforceCrossUserPermission(
6401             callingUid,
6402             userId,
6403             false /* requireFullPermission */,
6404             false /* checkShell */,
6405             "get installed application info");
6406
6407         // writer
6408         synchronized (mPackages) {
6409             ArrayList<ApplicationInfo> list;
6410             if (listUninstalled) {
6411                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
6412                 for (PackageSetting ps : mSettings.mPackages.values()) {
6413                     ApplicationInfo ai;
6414                     if (ps.pkg != null) {
6415                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
6416                                 ps.readUserState(userId), userId);
6417                     } else {
6418                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
6419                     }
6420                     if (ai != null) {
6421                         list.add(ai);
6422                     }
6423                 }
6424             } else {
6425                 list = new ArrayList<ApplicationInfo>(mPackages.size());
6426                 for (PackageParser.Package p : mPackages.values()) {
6427                     if (p.mExtras != null) {
6428                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6429                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
6430                         if (ai != null) {
6431                             list.add(ai);
6432                         }
6433                     }
6434                 }
6435             }
6436
6437             return new ParceledListSlice<ApplicationInfo>(list);
6438         }
6439     }
6440
6441     @Override
6442     public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
6443         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6444             return null;
6445         }
6446
6447         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6448                 "getEphemeralApplications");
6449         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6450                 true /* requireFullPermission */, false /* checkShell */,
6451                 "getEphemeralApplications");
6452         synchronized (mPackages) {
6453             List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
6454                     .getEphemeralApplicationsLPw(userId);
6455             if (ephemeralApps != null) {
6456                 return new ParceledListSlice<>(ephemeralApps);
6457             }
6458         }
6459         return null;
6460     }
6461
6462     @Override
6463     public boolean isEphemeralApplication(String packageName, int userId) {
6464         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6465                 true /* requireFullPermission */, false /* checkShell */,
6466                 "isEphemeral");
6467         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6468             return false;
6469         }
6470
6471         if (!isCallerSameApp(packageName)) {
6472             return false;
6473         }
6474         synchronized (mPackages) {
6475             PackageParser.Package pkg = mPackages.get(packageName);
6476             if (pkg != null) {
6477                 return pkg.applicationInfo.isEphemeralApp();
6478             }
6479         }
6480         return false;
6481     }
6482
6483     @Override
6484     public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
6485         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6486             return null;
6487         }
6488
6489         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6490                 true /* requireFullPermission */, false /* checkShell */,
6491                 "getCookie");
6492         if (!isCallerSameApp(packageName)) {
6493             return null;
6494         }
6495         synchronized (mPackages) {
6496             return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
6497                     packageName, userId);
6498         }
6499     }
6500
6501     @Override
6502     public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
6503         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6504             return true;
6505         }
6506
6507         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6508                 true /* requireFullPermission */, true /* checkShell */,
6509                 "setCookie");
6510         if (!isCallerSameApp(packageName)) {
6511             return false;
6512         }
6513         synchronized (mPackages) {
6514             return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
6515                     packageName, cookie, userId);
6516         }
6517     }
6518
6519     @Override
6520     public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
6521         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6522             return null;
6523         }
6524
6525         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6526                 "getEphemeralApplicationIcon");
6527         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6528                 true /* requireFullPermission */, false /* checkShell */,
6529                 "getEphemeralApplicationIcon");
6530         synchronized (mPackages) {
6531             return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
6532                     packageName, userId);
6533         }
6534     }
6535
6536     private boolean isCallerSameApp(String packageName) {
6537         PackageParser.Package pkg = mPackages.get(packageName);
6538         return pkg != null
6539                 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
6540     }
6541
6542     @Override
6543     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
6544         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
6545     }
6546
6547     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
6548         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
6549
6550         // reader
6551         synchronized (mPackages) {
6552             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
6553             final int userId = UserHandle.getCallingUserId();
6554             while (i.hasNext()) {
6555                 final PackageParser.Package p = i.next();
6556                 if (p.applicationInfo == null) continue;
6557
6558                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
6559                         && !p.applicationInfo.isDirectBootAware();
6560                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
6561                         && p.applicationInfo.isDirectBootAware();
6562
6563                 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
6564                         && (!mSafeMode || isSystemApp(p))
6565                         && (matchesUnaware || matchesAware)) {
6566                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
6567                     if (ps != null) {
6568                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6569                                 ps.readUserState(userId), userId);
6570                         if (ai != null) {
6571                             finalList.add(ai);
6572                         }
6573                     }
6574                 }
6575             }
6576         }
6577
6578         return finalList;
6579     }
6580
6581     @Override
6582     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
6583         if (!sUserManager.exists(userId)) return null;
6584         flags = updateFlagsForComponent(flags, userId, name);
6585         // reader
6586         synchronized (mPackages) {
6587             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
6588             PackageSetting ps = provider != null
6589                     ? mSettings.mPackages.get(provider.owner.packageName)
6590                     : null;
6591             return ps != null
6592                     && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
6593                     ? PackageParser.generateProviderInfo(provider, flags,
6594                             ps.readUserState(userId), userId)
6595                     : null;
6596         }
6597     }
6598
6599     /**
6600      * @deprecated
6601      */
6602     @Deprecated
6603     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
6604         // reader
6605         synchronized (mPackages) {
6606             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
6607                     .entrySet().iterator();
6608             final int userId = UserHandle.getCallingUserId();
6609             while (i.hasNext()) {
6610                 Map.Entry<String, PackageParser.Provider> entry = i.next();
6611                 PackageParser.Provider p = entry.getValue();
6612                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6613
6614                 if (ps != null && p.syncable
6615                         && (!mSafeMode || (p.info.applicationInfo.flags
6616                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
6617                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
6618                             ps.readUserState(userId), userId);
6619                     if (info != null) {
6620                         outNames.add(entry.getKey());
6621                         outInfo.add(info);
6622                     }
6623                 }
6624             }
6625         }
6626     }
6627
6628     @Override
6629     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
6630             int uid, int flags) {
6631         final int userId = processName != null ? UserHandle.getUserId(uid)
6632                 : UserHandle.getCallingUserId();
6633         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6634         flags = updateFlagsForComponent(flags, userId, processName);
6635
6636         ArrayList<ProviderInfo> finalList = null;
6637         // reader
6638         synchronized (mPackages) {
6639             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
6640             while (i.hasNext()) {
6641                 final PackageParser.Provider p = i.next();
6642                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6643                 if (ps != null && p.info.authority != null
6644                         && (processName == null
6645                                 || (p.info.processName.equals(processName)
6646                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
6647                         && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
6648                     if (finalList == null) {
6649                         finalList = new ArrayList<ProviderInfo>(3);
6650                     }
6651                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
6652                             ps.readUserState(userId), userId);
6653                     if (info != null) {
6654                         finalList.add(info);
6655                     }
6656                 }
6657             }
6658         }
6659
6660         if (finalList != null) {
6661             Collections.sort(finalList, mProviderInitOrderSorter);
6662             return new ParceledListSlice<ProviderInfo>(finalList);
6663         }
6664
6665         return ParceledListSlice.emptyList();
6666     }
6667
6668     @Override
6669     public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6670         // reader
6671         synchronized (mPackages) {
6672             final PackageParser.Instrumentation i = mInstrumentation.get(name);
6673             return PackageParser.generateInstrumentationInfo(i, flags);
6674         }
6675     }
6676
6677     @Override
6678     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
6679             String targetPackage, int flags) {
6680         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
6681     }
6682
6683     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
6684             int flags) {
6685         ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
6686
6687         // reader
6688         synchronized (mPackages) {
6689             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6690             while (i.hasNext()) {
6691                 final PackageParser.Instrumentation p = i.next();
6692                 if (targetPackage == null
6693                         || targetPackage.equals(p.info.targetPackage)) {
6694                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6695                             flags);
6696                     if (ii != null) {
6697                         finalList.add(ii);
6698                     }
6699                 }
6700             }
6701         }
6702
6703         return finalList;
6704     }
6705
6706     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6707         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6708         if (overlays == null) {
6709             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6710             return;
6711         }
6712         for (PackageParser.Package opkg : overlays.values()) {
6713             // Not much to do if idmap fails: we already logged the error
6714             // and we certainly don't want to abort installation of pkg simply
6715             // because an overlay didn't fit properly. For these reasons,
6716             // ignore the return value of createIdmapForPackagePairLI.
6717             createIdmapForPackagePairLI(pkg, opkg);
6718         }
6719     }
6720
6721     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6722             PackageParser.Package opkg) {
6723         if (!opkg.mTrustedOverlay) {
6724             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6725                     opkg.baseCodePath + ": overlay not trusted");
6726             return false;
6727         }
6728         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6729         if (overlaySet == null) {
6730             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6731                     opkg.baseCodePath + " but target package has no known overlays");
6732             return false;
6733         }
6734         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6735         // TODO: generate idmap for split APKs
6736         try {
6737             mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
6738         } catch (InstallerException e) {
6739             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6740                     + opkg.baseCodePath);
6741             return false;
6742         }
6743         PackageParser.Package[] overlayArray =
6744             overlaySet.values().toArray(new PackageParser.Package[0]);
6745         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6746             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6747                 return p1.mOverlayPriority - p2.mOverlayPriority;
6748             }
6749         };
6750         Arrays.sort(overlayArray, cmp);
6751
6752         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6753         int i = 0;
6754         for (PackageParser.Package p : overlayArray) {
6755             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6756         }
6757         return true;
6758     }
6759
6760     private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6761         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6762         try {
6763             scanDirLI(dir, parseFlags, scanFlags, currentTime);
6764         } finally {
6765             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6766         }
6767     }
6768
6769     private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6770         final File[] files = dir.listFiles();
6771         if (ArrayUtils.isEmpty(files)) {
6772             Log.d(TAG, "No files in app dir " + dir);
6773             return;
6774         }
6775
6776         if (DEBUG_PACKAGE_SCANNING) {
6777             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6778                     + " flags=0x" + Integer.toHexString(parseFlags));
6779         }
6780
6781         for (File file : files) {
6782             final boolean isPackage = (isApkFile(file) || file.isDirectory())
6783                     && !PackageInstallerService.isStageName(file.getName());
6784             if (!isPackage) {
6785                 // Ignore entries which are not packages
6786                 continue;
6787             }
6788             try {
6789                 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6790                         scanFlags, currentTime, null);
6791             } catch (PackageManagerException e) {
6792                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6793
6794                 // Delete invalid userdata apps
6795                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6796                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6797                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6798                     removeCodePathLI(file);
6799                 }
6800             }
6801         }
6802     }
6803
6804     private static File getSettingsProblemFile() {
6805         File dataDir = Environment.getDataDirectory();
6806         File systemDir = new File(dataDir, "system");
6807         File fname = new File(systemDir, "uiderrors.txt");
6808         return fname;
6809     }
6810
6811     static void reportSettingsProblem(int priority, String msg) {
6812         logCriticalInfo(priority, msg);
6813     }
6814
6815     static void logCriticalInfo(int priority, String msg) {
6816         Slog.println(priority, TAG, msg);
6817         EventLogTags.writePmCriticalInfo(msg);
6818         try {
6819             File fname = getSettingsProblemFile();
6820             FileOutputStream out = new FileOutputStream(fname, true);
6821             PrintWriter pw = new FastPrintWriter(out);
6822             SimpleDateFormat formatter = new SimpleDateFormat();
6823             String dateString = formatter.format(new Date(System.currentTimeMillis()));
6824             pw.println(dateString + ": " + msg);
6825             pw.close();
6826             FileUtils.setPermissions(
6827                     fname.toString(),
6828                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6829                     -1, -1);
6830         } catch (java.io.IOException e) {
6831         }
6832     }
6833
6834     private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
6835         if (srcFile.isDirectory()) {
6836             final File baseFile = new File(pkg.baseCodePath);
6837             long maxModifiedTime = baseFile.lastModified();
6838             if (pkg.splitCodePaths != null) {
6839                 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
6840                     final File splitFile = new File(pkg.splitCodePaths[i]);
6841                     maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
6842                 }
6843             }
6844             return maxModifiedTime;
6845         }
6846         return srcFile.lastModified();
6847     }
6848
6849     private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
6850             final int policyFlags) throws PackageManagerException {
6851         // When upgrading from pre-N MR1, verify the package time stamp using the package
6852         // directory and not the APK file.
6853         final long lastModifiedTime = mIsPreNMR1Upgrade
6854                 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
6855         if (ps != null
6856                 && ps.codePath.equals(srcFile)
6857                 && ps.timeStamp == lastModifiedTime
6858                 && !isCompatSignatureUpdateNeeded(pkg)
6859                 && !isRecoverSignatureUpdateNeeded(pkg)) {
6860             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6861             KeySetManagerService ksms = mSettings.mKeySetManagerService;
6862             ArraySet<PublicKey> signingKs;
6863             synchronized (mPackages) {
6864                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6865             }
6866             if (ps.signatures.mSignatures != null
6867                     && ps.signatures.mSignatures.length != 0
6868                     && signingKs != null) {
6869                 // Optimization: reuse the existing cached certificates
6870                 // if the package appears to be unchanged.
6871                 pkg.mSignatures = ps.signatures.mSignatures;
6872                 pkg.mSigningKeys = signingKs;
6873                 return;
6874             }
6875
6876             Slog.w(TAG, "PackageSetting for " + ps.name
6877                     + " is missing signatures.  Collecting certs again to recover them.");
6878         } else {
6879             Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
6880         }
6881
6882         try {
6883             PackageParser.collectCertificates(pkg, policyFlags);
6884         } catch (PackageParserException e) {
6885             throw PackageManagerException.from(e);
6886         }
6887     }
6888
6889     /**
6890      *  Traces a package scan.
6891      *  @see #scanPackageLI(File, int, int, long, UserHandle)
6892      */
6893     private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
6894             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6895         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6896         try {
6897             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6898         } finally {
6899             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6900         }
6901     }
6902
6903     /**
6904      *  Scans a package and returns the newly parsed package.
6905      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6906      */
6907     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6908             long currentTime, UserHandle user) throws PackageManagerException {
6909         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6910         PackageParser pp = new PackageParser();
6911         pp.setSeparateProcesses(mSeparateProcesses);
6912         pp.setOnlyCoreApps(mOnlyCore);
6913         pp.setDisplayMetrics(mMetrics);
6914
6915         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6916             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6917         }
6918
6919         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
6920         final PackageParser.Package pkg;
6921         try {
6922             pkg = pp.parsePackage(scanFile, parseFlags);
6923         } catch (PackageParserException e) {
6924             throw PackageManagerException.from(e);
6925         } finally {
6926             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6927         }
6928
6929         return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
6930     }
6931
6932     /**
6933      *  Scans a package and returns the newly parsed package.
6934      *  @throws PackageManagerException on a parse error.
6935      */
6936     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
6937             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
6938             throws PackageManagerException {
6939         // If the package has children and this is the first dive in the function
6940         // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
6941         // packages (parent and children) would be successfully scanned before the
6942         // actual scan since scanning mutates internal state and we want to atomically
6943         // install the package and its children.
6944         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
6945             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
6946                 scanFlags |= SCAN_CHECK_ONLY;
6947             }
6948         } else {
6949             scanFlags &= ~SCAN_CHECK_ONLY;
6950         }
6951
6952         // Scan the parent
6953         PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
6954                 scanFlags, currentTime, user);
6955
6956         // Scan the children
6957         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
6958         for (int i = 0; i < childCount; i++) {
6959             PackageParser.Package childPackage = pkg.childPackages.get(i);
6960             scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
6961                     currentTime, user);
6962         }
6963
6964
6965         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
6966             return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
6967         }
6968
6969         return scannedPkg;
6970     }
6971
6972     /**
6973      *  Scans a package and returns the newly parsed package.
6974      *  @throws PackageManagerException on a parse error.
6975      */
6976     private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
6977             int policyFlags, int scanFlags, long currentTime, UserHandle user)
6978             throws PackageManagerException {
6979         PackageSetting ps = null;
6980         PackageSetting updatedPkg;
6981         // reader
6982         synchronized (mPackages) {
6983             // Look to see if we already know about this package.
6984             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6985             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6986                 // This package has been renamed to its original name.  Let's
6987                 // use that.
6988                 ps = mSettings.peekPackageLPr(oldName);
6989             }
6990             // If there was no original package, see one for the real package name.
6991             if (ps == null) {
6992                 ps = mSettings.peekPackageLPr(pkg.packageName);
6993             }
6994             // Check to see if this package could be hiding/updating a system
6995             // package.  Must look for it either under the original or real
6996             // package name depending on our state.
6997             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6998             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6999
7000             // If this is a package we don't know about on the system partition, we
7001             // may need to remove disabled child packages on the system partition
7002             // or may need to not add child packages if the parent apk is updated
7003             // on the data partition and no longer defines this child package.
7004             if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
7005                 // If this is a parent package for an updated system app and this system
7006                 // app got an OTA update which no longer defines some of the child packages
7007                 // we have to prune them from the disabled system packages.
7008                 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
7009                 if (disabledPs != null) {
7010                     final int scannedChildCount = (pkg.childPackages != null)
7011                             ? pkg.childPackages.size() : 0;
7012                     final int disabledChildCount = disabledPs.childPackageNames != null
7013                             ? disabledPs.childPackageNames.size() : 0;
7014                     for (int i = 0; i < disabledChildCount; i++) {
7015                         String disabledChildPackageName = disabledPs.childPackageNames.get(i);
7016                         boolean disabledPackageAvailable = false;
7017                         for (int j = 0; j < scannedChildCount; j++) {
7018                             PackageParser.Package childPkg = pkg.childPackages.get(j);
7019                             if (childPkg.packageName.equals(disabledChildPackageName)) {
7020                                 disabledPackageAvailable = true;
7021                                 break;
7022                             }
7023                          }
7024                          if (!disabledPackageAvailable) {
7025                              mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
7026                          }
7027                     }
7028                 }
7029             }
7030         }
7031
7032         boolean updatedPkgBetter = false;
7033         // First check if this is a system package that may involve an update
7034         if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
7035             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
7036             // it needs to drop FLAG_PRIVILEGED.
7037             if (locationIsPrivileged(scanFile)) {
7038                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7039             } else {
7040                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7041             }
7042
7043             if (ps != null && !ps.codePath.equals(scanFile)) {
7044                 // The path has changed from what was last scanned...  check the
7045                 // version of the new path against what we have stored to determine
7046                 // what to do.
7047                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
7048                 if (pkg.mVersionCode <= ps.versionCode) {
7049                     // The system package has been updated and the code path does not match
7050                     // Ignore entry. Skip it.
7051                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
7052                             + " ignored: updated version " + ps.versionCode
7053                             + " better than this " + pkg.mVersionCode);
7054                     if (!updatedPkg.codePath.equals(scanFile)) {
7055                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
7056                                 + ps.name + " changing from " + updatedPkg.codePathString
7057                                 + " to " + scanFile);
7058                         updatedPkg.codePath = scanFile;
7059                         updatedPkg.codePathString = scanFile.toString();
7060                         updatedPkg.resourcePath = scanFile;
7061                         updatedPkg.resourcePathString = scanFile.toString();
7062                     }
7063                     updatedPkg.pkg = pkg;
7064                     updatedPkg.versionCode = pkg.mVersionCode;
7065
7066                     // Update the disabled system child packages to point to the package too.
7067                     final int childCount = updatedPkg.childPackageNames != null
7068                             ? updatedPkg.childPackageNames.size() : 0;
7069                     for (int i = 0; i < childCount; i++) {
7070                         String childPackageName = updatedPkg.childPackageNames.get(i);
7071                         PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
7072                                 childPackageName);
7073                         if (updatedChildPkg != null) {
7074                             updatedChildPkg.pkg = pkg;
7075                             updatedChildPkg.versionCode = pkg.mVersionCode;
7076                         }
7077                     }
7078
7079                     throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
7080                             + scanFile + " ignored: updated version " + ps.versionCode
7081                             + " better than this " + pkg.mVersionCode);
7082                 } else {
7083                     // The current app on the system partition is better than
7084                     // what we have updated to on the data partition; switch
7085                     // back to the system partition version.
7086                     // At this point, its safely assumed that package installation for
7087                     // apps in system partition will go through. If not there won't be a working
7088                     // version of the app
7089                     // writer
7090                     synchronized (mPackages) {
7091                         // Just remove the loaded entries from package lists.
7092                         mPackages.remove(ps.name);
7093                     }
7094
7095                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7096                             + " reverting from " + ps.codePathString
7097                             + ": new version " + pkg.mVersionCode
7098                             + " better than installed " + ps.versionCode);
7099
7100                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7101                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7102                     synchronized (mInstallLock) {
7103                         args.cleanUpResourcesLI();
7104                     }
7105                     synchronized (mPackages) {
7106                         mSettings.enableSystemPackageLPw(ps.name);
7107                     }
7108                     updatedPkgBetter = true;
7109                 }
7110             }
7111         }
7112
7113         if (updatedPkg != null) {
7114             // An updated system app will not have the PARSE_IS_SYSTEM flag set
7115             // initially
7116             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
7117
7118             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
7119             // flag set initially
7120             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
7121                 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
7122             }
7123         }
7124
7125         // Verify certificates against what was last scanned
7126         collectCertificatesLI(ps, pkg, scanFile, policyFlags);
7127
7128         /*
7129          * A new system app appeared, but we already had a non-system one of the
7130          * same name installed earlier.
7131          */
7132         boolean shouldHideSystemApp = false;
7133         if (updatedPkg == null && ps != null
7134                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
7135             /*
7136              * Check to make sure the signatures match first. If they don't,
7137              * wipe the installed application and its data.
7138              */
7139             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
7140                     != PackageManager.SIGNATURE_MATCH) {
7141                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
7142                         + " signatures don't match existing userdata copy; removing");
7143                 try (PackageFreezer freezer = freezePackage(pkg.packageName,
7144                         "scanPackageInternalLI")) {
7145                     deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
7146                 }
7147                 ps = null;
7148             } else {
7149                 /*
7150                  * If the newly-added system app is an older version than the
7151                  * already installed version, hide it. It will be scanned later
7152                  * and re-added like an update.
7153                  */
7154                 if (pkg.mVersionCode <= ps.versionCode) {
7155                     shouldHideSystemApp = true;
7156                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
7157                             + " but new version " + pkg.mVersionCode + " better than installed "
7158                             + ps.versionCode + "; hiding system");
7159                 } else {
7160                     /*
7161                      * The newly found system app is a newer version that the
7162                      * one previously installed. Simply remove the
7163                      * already-installed application and replace it with our own
7164                      * while keeping the application data.
7165                      */
7166                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7167                             + " reverting from " + ps.codePathString + ": new version "
7168                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
7169                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7170                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7171                     synchronized (mInstallLock) {
7172                         args.cleanUpResourcesLI();
7173                     }
7174                 }
7175             }
7176         }
7177
7178         // The apk is forward locked (not public) if its code and resources
7179         // are kept in different files. (except for app in either system or
7180         // vendor path).
7181         // TODO grab this value from PackageSettings
7182         if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7183             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
7184                 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
7185             }
7186         }
7187
7188         // TODO: extend to support forward-locked splits
7189         String resourcePath = null;
7190         String baseResourcePath = null;
7191         if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
7192             if (ps != null && ps.resourcePathString != null) {
7193                 resourcePath = ps.resourcePathString;
7194                 baseResourcePath = ps.resourcePathString;
7195             } else {
7196                 // Should not happen at all. Just log an error.
7197                 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
7198             }
7199         } else {
7200             resourcePath = pkg.codePath;
7201             baseResourcePath = pkg.baseCodePath;
7202         }
7203
7204         // Set application objects path explicitly.
7205         pkg.setApplicationVolumeUuid(pkg.volumeUuid);
7206         pkg.setApplicationInfoCodePath(pkg.codePath);
7207         pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
7208         pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
7209         pkg.setApplicationInfoResourcePath(resourcePath);
7210         pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
7211         pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
7212
7213         // Note that we invoke the following method only if we are about to unpack an application
7214         PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
7215                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
7216
7217         /*
7218          * If the system app should be overridden by a previously installed
7219          * data, hide the system app now and let the /data/app scan pick it up
7220          * again.
7221          */
7222         if (shouldHideSystemApp) {
7223             synchronized (mPackages) {
7224                 mSettings.disableSystemPackageLPw(pkg.packageName, true);
7225             }
7226         }
7227
7228         return scannedPkg;
7229     }
7230
7231     private static String fixProcessName(String defProcessName,
7232             String processName, int uid) {
7233         if (processName == null) {
7234             return defProcessName;
7235         }
7236         return processName;
7237     }
7238
7239     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
7240             throws PackageManagerException {
7241         if (pkgSetting.signatures.mSignatures != null) {
7242             // Already existing package. Make sure signatures match
7243             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
7244                     == PackageManager.SIGNATURE_MATCH;
7245             if (!match) {
7246                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
7247                         == PackageManager.SIGNATURE_MATCH;
7248             }
7249             if (!match) {
7250                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
7251                         == PackageManager.SIGNATURE_MATCH;
7252             }
7253             if (!match) {
7254                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
7255                         + pkg.packageName + " signatures do not match the "
7256                         + "previously installed version; ignoring!");
7257             }
7258         }
7259
7260         // Check for shared user signatures
7261         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
7262             // Already existing package. Make sure signatures match
7263             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7264                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
7265             if (!match) {
7266                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
7267                         == PackageManager.SIGNATURE_MATCH;
7268             }
7269             if (!match) {
7270                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
7271                         == PackageManager.SIGNATURE_MATCH;
7272             }
7273             if (!match) {
7274                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
7275                         "Package " + pkg.packageName
7276                         + " has no signatures that match those in shared user "
7277                         + pkgSetting.sharedUser.name + "; ignoring!");
7278             }
7279         }
7280     }
7281
7282     /**
7283      * Enforces that only the system UID or root's UID can call a method exposed
7284      * via Binder.
7285      *
7286      * @param message used as message if SecurityException is thrown
7287      * @throws SecurityException if the caller is not system or root
7288      */
7289     private static final void enforceSystemOrRoot(String message) {
7290         final int uid = Binder.getCallingUid();
7291         if (uid != Process.SYSTEM_UID && uid != 0) {
7292             throw new SecurityException(message);
7293         }
7294     }
7295
7296     @Override
7297     public void performFstrimIfNeeded() {
7298         enforceSystemOrRoot("Only the system can request fstrim");
7299
7300         // Before everything else, see whether we need to fstrim.
7301         try {
7302             IMountService ms = PackageHelper.getMountService();
7303             if (ms != null) {
7304                 boolean doTrim = false;
7305                 final long interval = android.provider.Settings.Global.getLong(
7306                         mContext.getContentResolver(),
7307                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
7308                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
7309                 if (interval > 0) {
7310                     final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
7311                     if (timeSinceLast > interval) {
7312                         doTrim = true;
7313                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
7314                                 + "; running immediately");
7315                     }
7316                 }
7317                 if (doTrim) {
7318                     final boolean dexOptDialogShown;
7319                     synchronized (mPackages) {
7320                         dexOptDialogShown = mDexOptDialogShown;
7321                     }
7322                     if (!isFirstBoot() && dexOptDialogShown) {
7323                         try {
7324                             ActivityManagerNative.getDefault().showBootMessage(
7325                                     mContext.getResources().getString(
7326                                             R.string.android_upgrading_fstrim), true);
7327                         } catch (RemoteException e) {
7328                         }
7329                     }
7330                     ms.runMaintenance();
7331                 }
7332             } else {
7333                 Slog.e(TAG, "Mount service unavailable!");
7334             }
7335         } catch (RemoteException e) {
7336             // Can't happen; MountService is local
7337         }
7338     }
7339
7340     @Override
7341     public void updatePackagesIfNeeded() {
7342         enforceSystemOrRoot("Only the system can request package update");
7343
7344         // We need to re-extract after an OTA.
7345         boolean causeUpgrade = isUpgrade();
7346
7347         // First boot or factory reset.
7348         // Note: we also handle devices that are upgrading to N right now as if it is their
7349         //       first boot, as they do not have profile data.
7350         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
7351
7352         // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
7353         boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
7354
7355         if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
7356             return;
7357         }
7358
7359         List<PackageParser.Package> pkgs;
7360         synchronized (mPackages) {
7361             pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
7362         }
7363
7364         final long startTime = System.nanoTime();
7365         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
7366                     getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
7367
7368         final int elapsedTimeSeconds =
7369                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
7370
7371         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
7372         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
7373         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
7374         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
7375         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
7376     }
7377
7378     /**
7379      * Performs dexopt on the set of packages in {@code packages} and returns an int array
7380      * containing statistics about the invocation. The array consists of three elements,
7381      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
7382      * and {@code numberOfPackagesFailed}.
7383      */
7384     private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
7385             String compilerFilter) {
7386
7387         int numberOfPackagesVisited = 0;
7388         int numberOfPackagesOptimized = 0;
7389         int numberOfPackagesSkipped = 0;
7390         int numberOfPackagesFailed = 0;
7391         final int numberOfPackagesToDexopt = pkgs.size();
7392
7393         for (PackageParser.Package pkg : pkgs) {
7394             numberOfPackagesVisited++;
7395
7396             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
7397                 if (DEBUG_DEXOPT) {
7398                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
7399                 }
7400                 numberOfPackagesSkipped++;
7401                 continue;
7402             }
7403
7404             if (DEBUG_DEXOPT) {
7405                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
7406                         numberOfPackagesToDexopt + ": " + pkg.packageName);
7407             }
7408
7409             if (showDialog) {
7410                 try {
7411                     ActivityManagerNative.getDefault().showBootMessage(
7412                             mContext.getResources().getString(R.string.android_upgrading_apk,
7413                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
7414                 } catch (RemoteException e) {
7415                 }
7416                 synchronized (mPackages) {
7417                     mDexOptDialogShown = true;
7418                 }
7419             }
7420
7421             // If the OTA updates a system app which was previously preopted to a non-preopted state
7422             // the app might end up being verified at runtime. That's because by default the apps
7423             // are verify-profile but for preopted apps there's no profile.
7424             // Do a hacky check to ensure that if we have no profiles (a reasonable indication
7425             // that before the OTA the app was preopted) the app gets compiled with a non-profile
7426             // filter (by default interpret-only).
7427             // Note that at this stage unused apps are already filtered.
7428             if (isSystemApp(pkg) &&
7429                     DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
7430                     !Environment.getReferenceProfile(pkg.packageName).exists()) {
7431                 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
7432             }
7433
7434             // checkProfiles is false to avoid merging profiles during boot which
7435             // might interfere with background compilation (b/28612421).
7436             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
7437             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
7438             // trade-off worth doing to save boot time work.
7439             int dexOptStatus = performDexOptTraced(pkg.packageName,
7440                     false /* checkProfiles */,
7441                     compilerFilter,
7442                     false /* force */);
7443             switch (dexOptStatus) {
7444                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
7445                     numberOfPackagesOptimized++;
7446                     break;
7447                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
7448                     numberOfPackagesSkipped++;
7449                     break;
7450                 case PackageDexOptimizer.DEX_OPT_FAILED:
7451                     numberOfPackagesFailed++;
7452                     break;
7453                 default:
7454                     Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
7455                     break;
7456             }
7457         }
7458
7459         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
7460                 numberOfPackagesFailed };
7461     }
7462
7463     @Override
7464     public void notifyPackageUse(String packageName, int reason) {
7465         synchronized (mPackages) {
7466             PackageParser.Package p = mPackages.get(packageName);
7467             if (p == null) {
7468                 return;
7469             }
7470             p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
7471         }
7472     }
7473
7474     // TODO: this is not used nor needed. Delete it.
7475     @Override
7476     public boolean performDexOptIfNeeded(String packageName) {
7477         int dexOptStatus = performDexOptTraced(packageName,
7478                 false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
7479         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7480     }
7481
7482     @Override
7483     public boolean performDexOpt(String packageName,
7484             boolean checkProfiles, int compileReason, boolean force) {
7485         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7486                 getCompilerFilterForReason(compileReason), force);
7487         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7488     }
7489
7490     @Override
7491     public boolean performDexOptMode(String packageName,
7492             boolean checkProfiles, String targetCompilerFilter, boolean force) {
7493         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7494                 targetCompilerFilter, force);
7495         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7496     }
7497
7498     private int performDexOptTraced(String packageName,
7499                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
7500         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7501         try {
7502             return performDexOptInternal(packageName, checkProfiles,
7503                     targetCompilerFilter, force);
7504         } finally {
7505             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7506         }
7507     }
7508
7509     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
7510     // if the package can now be considered up to date for the given filter.
7511     private int performDexOptInternal(String packageName,
7512                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
7513         PackageParser.Package p;
7514         synchronized (mPackages) {
7515             p = mPackages.get(packageName);
7516             if (p == null) {
7517                 // Package could not be found. Report failure.
7518                 return PackageDexOptimizer.DEX_OPT_FAILED;
7519             }
7520             mPackageUsage.maybeWriteAsync(mPackages);
7521             mCompilerStats.maybeWriteAsync();
7522         }
7523         long callingId = Binder.clearCallingIdentity();
7524         try {
7525             synchronized (mInstallLock) {
7526                 return performDexOptInternalWithDependenciesLI(p, checkProfiles,
7527                         targetCompilerFilter, force);
7528             }
7529         } finally {
7530             Binder.restoreCallingIdentity(callingId);
7531         }
7532     }
7533
7534     public ArraySet<String> getOptimizablePackages() {
7535         ArraySet<String> pkgs = new ArraySet<String>();
7536         synchronized (mPackages) {
7537             for (PackageParser.Package p : mPackages.values()) {
7538                 if (PackageDexOptimizer.canOptimizePackage(p)) {
7539                     pkgs.add(p.packageName);
7540                 }
7541             }
7542         }
7543         return pkgs;
7544     }
7545
7546     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
7547             boolean checkProfiles, String targetCompilerFilter,
7548             boolean force) {
7549         // Select the dex optimizer based on the force parameter.
7550         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
7551         //       allocate an object here.
7552         PackageDexOptimizer pdo = force
7553                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
7554                 : mPackageDexOptimizer;
7555
7556         // Optimize all dependencies first. Note: we ignore the return value and march on
7557         // on errors.
7558         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
7559         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
7560         if (!deps.isEmpty()) {
7561             for (PackageParser.Package depPackage : deps) {
7562                 // TODO: Analyze and investigate if we (should) profile libraries.
7563                 // Currently this will do a full compilation of the library by default.
7564                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
7565                         false /* checkProfiles */,
7566                         getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
7567                         getOrCreateCompilerPackageStats(depPackage));
7568             }
7569         }
7570         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
7571                 targetCompilerFilter, getOrCreateCompilerPackageStats(p));
7572     }
7573
7574     Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
7575         if (p.usesLibraries != null || p.usesOptionalLibraries != null) {
7576             ArrayList<PackageParser.Package> retValue = new ArrayList<>();
7577             Set<String> collectedNames = new HashSet<>();
7578             findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
7579
7580             retValue.remove(p);
7581
7582             return retValue;
7583         } else {
7584             return Collections.emptyList();
7585         }
7586     }
7587
7588     private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
7589             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7590         if (!collectedNames.contains(p.packageName)) {
7591             collectedNames.add(p.packageName);
7592             collected.add(p);
7593
7594             if (p.usesLibraries != null) {
7595                 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames);
7596             }
7597             if (p.usesOptionalLibraries != null) {
7598                 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected,
7599                         collectedNames);
7600             }
7601         }
7602     }
7603
7604     private void findSharedNonSystemLibrariesRecursive(Collection<String> libs,
7605             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7606         for (String libName : libs) {
7607             PackageParser.Package libPkg = findSharedNonSystemLibrary(libName);
7608             if (libPkg != null) {
7609                 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
7610             }
7611         }
7612     }
7613
7614     private PackageParser.Package findSharedNonSystemLibrary(String libName) {
7615         synchronized (mPackages) {
7616             PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
7617             if (lib != null && lib.apk != null) {
7618                 return mPackages.get(lib.apk);
7619             }
7620         }
7621         return null;
7622     }
7623
7624     public void shutdown() {
7625         mPackageUsage.writeNow(mPackages);
7626         mCompilerStats.writeNow();
7627     }
7628
7629     @Override
7630     public void dumpProfiles(String packageName) {
7631         PackageParser.Package pkg;
7632         synchronized (mPackages) {
7633             pkg = mPackages.get(packageName);
7634             if (pkg == null) {
7635                 throw new IllegalArgumentException("Unknown package: " + packageName);
7636             }
7637         }
7638         /* Only the shell, root, or the app user should be able to dump profiles. */
7639         int callingUid = Binder.getCallingUid();
7640         if (callingUid != Process.SHELL_UID &&
7641             callingUid != Process.ROOT_UID &&
7642             callingUid != pkg.applicationInfo.uid) {
7643             throw new SecurityException("dumpProfiles");
7644         }
7645
7646         synchronized (mInstallLock) {
7647             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
7648             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
7649             try {
7650                 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
7651                 String gid = Integer.toString(sharedGid);
7652                 String codePaths = TextUtils.join(";", allCodePaths);
7653                 mInstaller.dumpProfiles(gid, packageName, codePaths);
7654             } catch (InstallerException e) {
7655                 Slog.w(TAG, "Failed to dump profiles", e);
7656             }
7657             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7658         }
7659     }
7660
7661     @Override
7662     public void forceDexOpt(String packageName) {
7663         enforceSystemOrRoot("forceDexOpt");
7664
7665         PackageParser.Package pkg;
7666         synchronized (mPackages) {
7667             pkg = mPackages.get(packageName);
7668             if (pkg == null) {
7669                 throw new IllegalArgumentException("Unknown package: " + packageName);
7670             }
7671         }
7672
7673         synchronized (mInstallLock) {
7674             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7675
7676             // Whoever is calling forceDexOpt wants a fully compiled package.
7677             // Don't use profiles since that may cause compilation to be skipped.
7678             final int res = performDexOptInternalWithDependenciesLI(pkg,
7679                     false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
7680                     true /* force */);
7681
7682             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7683             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
7684                 throw new IllegalStateException("Failed to dexopt: " + res);
7685             }
7686         }
7687     }
7688
7689     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
7690         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7691             Slog.w(TAG, "Unable to update from " + oldPkg.name
7692                     + " to " + newPkg.packageName
7693                     + ": old package not in system partition");
7694             return false;
7695         } else if (mPackages.get(oldPkg.name) != null) {
7696             Slog.w(TAG, "Unable to update from " + oldPkg.name
7697                     + " to " + newPkg.packageName
7698                     + ": old package still exists");
7699             return false;
7700         }
7701         return true;
7702     }
7703
7704     void removeCodePathLI(File codePath) {
7705         if (codePath.isDirectory()) {
7706             try {
7707                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
7708             } catch (InstallerException e) {
7709                 Slog.w(TAG, "Failed to remove code path", e);
7710             }
7711         } else {
7712             codePath.delete();
7713         }
7714     }
7715
7716     private int[] resolveUserIds(int userId) {
7717         return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
7718     }
7719
7720     private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7721         if (pkg == null) {
7722             Slog.wtf(TAG, "Package was null!", new Throwable());
7723             return;
7724         }
7725         clearAppDataLeafLIF(pkg, userId, flags);
7726         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7727         for (int i = 0; i < childCount; i++) {
7728             clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7729         }
7730     }
7731
7732     private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7733         final PackageSetting ps;
7734         synchronized (mPackages) {
7735             ps = mSettings.mPackages.get(pkg.packageName);
7736         }
7737         for (int realUserId : resolveUserIds(userId)) {
7738             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7739             try {
7740                 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7741                         ceDataInode);
7742             } catch (InstallerException e) {
7743                 Slog.w(TAG, String.valueOf(e));
7744             }
7745         }
7746     }
7747
7748     private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7749         if (pkg == null) {
7750             Slog.wtf(TAG, "Package was null!", new Throwable());
7751             return;
7752         }
7753         destroyAppDataLeafLIF(pkg, userId, flags);
7754         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7755         for (int i = 0; i < childCount; i++) {
7756             destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7757         }
7758     }
7759
7760     private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7761         final PackageSetting ps;
7762         synchronized (mPackages) {
7763             ps = mSettings.mPackages.get(pkg.packageName);
7764         }
7765         for (int realUserId : resolveUserIds(userId)) {
7766             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7767             try {
7768                 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7769                         ceDataInode);
7770             } catch (InstallerException e) {
7771                 Slog.w(TAG, String.valueOf(e));
7772             }
7773         }
7774     }
7775
7776     private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
7777         if (pkg == null) {
7778             Slog.wtf(TAG, "Package was null!", new Throwable());
7779             return;
7780         }
7781         destroyAppProfilesLeafLIF(pkg);
7782         destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */);
7783         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7784         for (int i = 0; i < childCount; i++) {
7785             destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
7786             destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId,
7787                     true /* removeBaseMarker */);
7788         }
7789     }
7790
7791     private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId,
7792             boolean removeBaseMarker) {
7793         if (pkg.isForwardLocked()) {
7794             return;
7795         }
7796
7797         for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
7798             try {
7799                 path = PackageManagerServiceUtils.realpath(new File(path));
7800             } catch (IOException e) {
7801                 // TODO: Should we return early here ?
7802                 Slog.w(TAG, "Failed to get canonical path", e);
7803                 continue;
7804             }
7805
7806             final String useMarker = path.replace('/', '@');
7807             for (int realUserId : resolveUserIds(userId)) {
7808                 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId);
7809                 if (removeBaseMarker) {
7810                     File foreignUseMark = new File(profileDir, useMarker);
7811                     if (foreignUseMark.exists()) {
7812                         if (!foreignUseMark.delete()) {
7813                             Slog.w(TAG, "Unable to delete foreign user mark for package: "
7814                                     + pkg.packageName);
7815                         }
7816                     }
7817                 }
7818
7819                 File[] markers = profileDir.listFiles();
7820                 if (markers != null) {
7821                     final String searchString = "@" + pkg.packageName + "@";
7822                     // We also delete all markers that contain the package name we're
7823                     // uninstalling. These are associated with secondary dex-files belonging
7824                     // to the package. Reconstructing the path of these dex files is messy
7825                     // in general.
7826                     for (File marker : markers) {
7827                         if (marker.getName().indexOf(searchString) > 0) {
7828                             if (!marker.delete()) {
7829                                 Slog.w(TAG, "Unable to delete foreign user mark for package: "
7830                                     + pkg.packageName);
7831                             }
7832                         }
7833                     }
7834                 }
7835             }
7836         }
7837     }
7838
7839     private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
7840         try {
7841             mInstaller.destroyAppProfiles(pkg.packageName);
7842         } catch (InstallerException e) {
7843             Slog.w(TAG, String.valueOf(e));
7844         }
7845     }
7846
7847     private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
7848         if (pkg == null) {
7849             Slog.wtf(TAG, "Package was null!", new Throwable());
7850             return;
7851         }
7852         clearAppProfilesLeafLIF(pkg);
7853         // We don't remove the base foreign use marker when clearing profiles because
7854         // we will rename it when the app is updated. Unlike the actual profile contents,
7855         // the foreign use marker is good across installs.
7856         destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */);
7857         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7858         for (int i = 0; i < childCount; i++) {
7859             clearAppProfilesLeafLIF(pkg.childPackages.get(i));
7860         }
7861     }
7862
7863     private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
7864         try {
7865             mInstaller.clearAppProfiles(pkg.packageName);
7866         } catch (InstallerException e) {
7867             Slog.w(TAG, String.valueOf(e));
7868         }
7869     }
7870
7871     private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
7872             long lastUpdateTime) {
7873         // Set parent install/update time
7874         PackageSetting ps = (PackageSetting) pkg.mExtras;
7875         if (ps != null) {
7876             ps.firstInstallTime = firstInstallTime;
7877             ps.lastUpdateTime = lastUpdateTime;
7878         }
7879         // Set children install/update time
7880         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7881         for (int i = 0; i < childCount; i++) {
7882             PackageParser.Package childPkg = pkg.childPackages.get(i);
7883             ps = (PackageSetting) childPkg.mExtras;
7884             if (ps != null) {
7885                 ps.firstInstallTime = firstInstallTime;
7886                 ps.lastUpdateTime = lastUpdateTime;
7887             }
7888         }
7889     }
7890
7891     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
7892             PackageParser.Package changingLib) {
7893         if (file.path != null) {
7894             usesLibraryFiles.add(file.path);
7895             return;
7896         }
7897         PackageParser.Package p = mPackages.get(file.apk);
7898         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
7899             // If we are doing this while in the middle of updating a library apk,
7900             // then we need to make sure to use that new apk for determining the
7901             // dependencies here.  (We haven't yet finished committing the new apk
7902             // to the package manager state.)
7903             if (p == null || p.packageName.equals(changingLib.packageName)) {
7904                 p = changingLib;
7905             }
7906         }
7907         if (p != null) {
7908             usesLibraryFiles.addAll(p.getAllCodePaths());
7909         }
7910     }
7911
7912     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
7913             PackageParser.Package changingLib) throws PackageManagerException {
7914         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
7915             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
7916             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
7917             for (int i=0; i<N; i++) {
7918                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
7919                 if (file == null) {
7920                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
7921                             "Package " + pkg.packageName + " requires unavailable shared library "
7922                             + pkg.usesLibraries.get(i) + "; failing!");
7923                 }
7924                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7925             }
7926             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
7927             for (int i=0; i<N; i++) {
7928                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
7929                 if (file == null) {
7930                     Slog.w(TAG, "Package " + pkg.packageName
7931                             + " desires unavailable shared library "
7932                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
7933                 } else {
7934                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7935                 }
7936             }
7937             N = usesLibraryFiles.size();
7938             if (N > 0) {
7939                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
7940             } else {
7941                 pkg.usesLibraryFiles = null;
7942             }
7943         }
7944     }
7945
7946     private static boolean hasString(List<String> list, List<String> which) {
7947         if (list == null) {
7948             return false;
7949         }
7950         for (int i=list.size()-1; i>=0; i--) {
7951             for (int j=which.size()-1; j>=0; j--) {
7952                 if (which.get(j).equals(list.get(i))) {
7953                     return true;
7954                 }
7955             }
7956         }
7957         return false;
7958     }
7959
7960     private void updateAllSharedLibrariesLPw() {
7961         for (PackageParser.Package pkg : mPackages.values()) {
7962             try {
7963                 updateSharedLibrariesLPw(pkg, null);
7964             } catch (PackageManagerException e) {
7965                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7966             }
7967         }
7968     }
7969
7970     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
7971             PackageParser.Package changingPkg) {
7972         ArrayList<PackageParser.Package> res = null;
7973         for (PackageParser.Package pkg : mPackages.values()) {
7974             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
7975                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
7976                 if (res == null) {
7977                     res = new ArrayList<PackageParser.Package>();
7978                 }
7979                 res.add(pkg);
7980                 try {
7981                     updateSharedLibrariesLPw(pkg, changingPkg);
7982                 } catch (PackageManagerException e) {
7983                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7984                 }
7985             }
7986         }
7987         return res;
7988     }
7989
7990     /**
7991      * Derive the value of the {@code cpuAbiOverride} based on the provided
7992      * value and an optional stored value from the package settings.
7993      */
7994     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
7995         String cpuAbiOverride = null;
7996
7997         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
7998             cpuAbiOverride = null;
7999         } else if (abiOverride != null) {
8000             cpuAbiOverride = abiOverride;
8001         } else if (settings != null) {
8002             cpuAbiOverride = settings.cpuAbiOverrideString;
8003         }
8004
8005         return cpuAbiOverride;
8006     }
8007
8008     private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
8009             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
8010                     throws PackageManagerException {
8011         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
8012         // If the package has children and this is the first dive in the function
8013         // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
8014         // whether all packages (parent and children) would be successfully scanned
8015         // before the actual scan since scanning mutates internal state and we want
8016         // to atomically install the package and its children.
8017         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8018             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8019                 scanFlags |= SCAN_CHECK_ONLY;
8020             }
8021         } else {
8022             scanFlags &= ~SCAN_CHECK_ONLY;
8023         }
8024
8025         final PackageParser.Package scannedPkg;
8026         try {
8027             // Scan the parent
8028             scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
8029             // Scan the children
8030             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8031             for (int i = 0; i < childCount; i++) {
8032                 PackageParser.Package childPkg = pkg.childPackages.get(i);
8033                 scanPackageLI(childPkg, policyFlags,
8034                         scanFlags, currentTime, user);
8035             }
8036         } finally {
8037             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8038         }
8039
8040         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8041             return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
8042         }
8043
8044         return scannedPkg;
8045     }
8046
8047     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
8048             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8049         boolean success = false;
8050         try {
8051             final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
8052                     currentTime, user);
8053             success = true;
8054             return res;
8055         } finally {
8056             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
8057                 // DELETE_DATA_ON_FAILURES is only used by frozen paths
8058                 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
8059                         StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
8060                 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
8061             }
8062         }
8063     }
8064
8065     /**
8066      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
8067      */
8068     private static boolean apkHasCode(String fileName) {
8069         StrictJarFile jarFile = null;
8070         try {
8071             jarFile = new StrictJarFile(fileName,
8072                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
8073             return jarFile.findEntry("classes.dex") != null;
8074         } catch (IOException ignore) {
8075         } finally {
8076             try {
8077                 if (jarFile != null) {
8078                     jarFile.close();
8079                 }
8080             } catch (IOException ignore) {}
8081         }
8082         return false;
8083     }
8084
8085     /**
8086      * Enforces code policy for the package. This ensures that if an APK has
8087      * declared hasCode="true" in its manifest that the APK actually contains
8088      * code.
8089      *
8090      * @throws PackageManagerException If bytecode could not be found when it should exist
8091      */
8092     private static void enforceCodePolicy(PackageParser.Package pkg)
8093             throws PackageManagerException {
8094         final boolean shouldHaveCode =
8095                 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
8096         if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
8097             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8098                     "Package " + pkg.baseCodePath + " code is missing");
8099         }
8100
8101         if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8102             for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8103                 final boolean splitShouldHaveCode =
8104                         (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
8105                 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
8106                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8107                             "Package " + pkg.splitCodePaths[i] + " code is missing");
8108                 }
8109             }
8110         }
8111     }
8112
8113     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
8114             final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
8115             throws PackageManagerException {
8116         final File scanFile = new File(pkg.codePath);
8117         if (pkg.applicationInfo.getCodePath() == null ||
8118                 pkg.applicationInfo.getResourcePath() == null) {
8119             // Bail out. The resource and code paths haven't been set.
8120             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8121                     "Code and resource paths haven't been set correctly");
8122         }
8123
8124         // Apply policy
8125         if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
8126             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
8127             if (pkg.applicationInfo.isDirectBootAware()) {
8128                 // we're direct boot aware; set for all components
8129                 for (PackageParser.Service s : pkg.services) {
8130                     s.info.encryptionAware = s.info.directBootAware = true;
8131                 }
8132                 for (PackageParser.Provider p : pkg.providers) {
8133                     p.info.encryptionAware = p.info.directBootAware = true;
8134                 }
8135                 for (PackageParser.Activity a : pkg.activities) {
8136                     a.info.encryptionAware = a.info.directBootAware = true;
8137                 }
8138                 for (PackageParser.Activity r : pkg.receivers) {
8139                     r.info.encryptionAware = r.info.directBootAware = true;
8140                 }
8141             }
8142         } else {
8143             // Only allow system apps to be flagged as core apps.
8144             pkg.coreApp = false;
8145             // clear flags not applicable to regular apps
8146             pkg.applicationInfo.privateFlags &=
8147                     ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
8148             pkg.applicationInfo.privateFlags &=
8149                     ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
8150         }
8151         pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
8152
8153         if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
8154             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8155         }
8156
8157         if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
8158             enforceCodePolicy(pkg);
8159         }
8160
8161         if (mCustomResolverComponentName != null &&
8162                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
8163             setUpCustomResolverActivity(pkg);
8164         }
8165
8166         if (pkg.packageName.equals("android")) {
8167             synchronized (mPackages) {
8168                 if (mAndroidApplication != null) {
8169                     Slog.w(TAG, "*************************************************");
8170                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
8171                     Slog.w(TAG, " file=" + scanFile);
8172                     Slog.w(TAG, "*************************************************");
8173                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
8174                             "Core android package being redefined.  Skipping.");
8175                 }
8176
8177                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8178                     // Set up information for our fall-back user intent resolution activity.
8179                     mPlatformPackage = pkg;
8180                     pkg.mVersionCode = mSdkVersion;
8181                     mAndroidApplication = pkg.applicationInfo;
8182
8183                     if (!mResolverReplaced) {
8184                         mResolveActivity.applicationInfo = mAndroidApplication;
8185                         mResolveActivity.name = ResolverActivity.class.getName();
8186                         mResolveActivity.packageName = mAndroidApplication.packageName;
8187                         mResolveActivity.processName = "system:ui";
8188                         mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8189                         mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
8190                         mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
8191                         mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
8192                         mResolveActivity.exported = true;
8193                         mResolveActivity.enabled = true;
8194                         mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
8195                         mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
8196                                 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
8197                                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
8198                                 | ActivityInfo.CONFIG_ORIENTATION
8199                                 | ActivityInfo.CONFIG_KEYBOARD
8200                                 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
8201                         mResolveInfo.activityInfo = mResolveActivity;
8202                         mResolveInfo.priority = 0;
8203                         mResolveInfo.preferredOrder = 0;
8204                         mResolveInfo.match = 0;
8205                         mResolveComponentName = new ComponentName(
8206                                 mAndroidApplication.packageName, mResolveActivity.name);
8207                     }
8208                 }
8209             }
8210         }
8211
8212         if (DEBUG_PACKAGE_SCANNING) {
8213             if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8214                 Log.d(TAG, "Scanning package " + pkg.packageName);
8215         }
8216
8217         final PackageParser.Package oldPkg;
8218
8219         synchronized (mPackages) {
8220             if (mPackages.containsKey(pkg.packageName)
8221                     || mSharedLibraries.containsKey(pkg.packageName)) {
8222                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
8223                         "Application package " + pkg.packageName
8224                                 + " already installed.  Skipping duplicate.");
8225             }
8226
8227             final PackageSetting oldPkgSetting = mSettings.peekPackageLPr(pkg.packageName);
8228             if (oldPkgSetting == null) {
8229                oldPkg = null;
8230             } else {
8231                oldPkg = oldPkgSetting.pkg;
8232             }
8233
8234             // If we're only installing presumed-existing packages, require that the
8235             // scanned APK is both already known and at the path previously established
8236             // for it.  Previously unknown packages we pick up normally, but if we have an
8237             // a priori expectation about this package's install presence, enforce it.
8238             // With a singular exception for new system packages. When an OTA contains
8239             // a new system package, we allow the codepath to change from a system location
8240             // to the user-installed location. If we don't allow this change, any newer,
8241             // user-installed version of the application will be ignored.
8242             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
8243                 if (mExpectingBetter.containsKey(pkg.packageName)) {
8244                     logCriticalInfo(Log.WARN,
8245                             "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
8246                 } else {
8247                     PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
8248                     if (known != null) {
8249                         if (DEBUG_PACKAGE_SCANNING) {
8250                             Log.d(TAG, "Examining " + pkg.codePath
8251                                     + " and requiring known paths " + known.codePathString
8252                                     + " & " + known.resourcePathString);
8253                         }
8254                         if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
8255                                 || !pkg.applicationInfo.getResourcePath().equals(
8256                                 known.resourcePathString)) {
8257                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
8258                                     "Application package " + pkg.packageName
8259                                             + " found at " + pkg.applicationInfo.getCodePath()
8260                                             + " but expected at " + known.codePathString
8261                                             + "; ignoring.");
8262                         }
8263                     }
8264                 }
8265             }
8266         }
8267
8268         // Initialize package source and resource directories
8269         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
8270         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
8271
8272         SharedUserSetting suid = null;
8273         PackageSetting pkgSetting = null;
8274
8275         if (!isSystemApp(pkg)) {
8276             // Only system apps can use these features.
8277             pkg.mOriginalPackages = null;
8278             pkg.mRealPackage = null;
8279             pkg.mAdoptPermissions = null;
8280         }
8281
8282         // Getting the package setting may have a side-effect, so if we
8283         // are only checking if scan would succeed, stash a copy of the
8284         // old setting to restore at the end.
8285         PackageSetting nonMutatedPs = null;
8286
8287         // writer
8288         synchronized (mPackages) {
8289             if (pkg.mSharedUserId != null) {
8290                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
8291                 if (suid == null) {
8292                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8293                             "Creating application package " + pkg.packageName
8294                             + " for shared user failed");
8295                 }
8296                 if (DEBUG_PACKAGE_SCANNING) {
8297                     if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8298                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
8299                                 + "): packages=" + suid.packages);
8300                 }
8301             }
8302
8303             // Check if we are renaming from an original package name.
8304             PackageSetting origPackage = null;
8305             String realName = null;
8306             if (pkg.mOriginalPackages != null) {
8307                 // This package may need to be renamed to a previously
8308                 // installed name.  Let's check on that...
8309                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
8310                 if (pkg.mOriginalPackages.contains(renamed)) {
8311                     // This package had originally been installed as the
8312                     // original name, and we have already taken care of
8313                     // transitioning to the new one.  Just update the new
8314                     // one to continue using the old name.
8315                     realName = pkg.mRealPackage;
8316                     if (!pkg.packageName.equals(renamed)) {
8317                         // Callers into this function may have already taken
8318                         // care of renaming the package; only do it here if
8319                         // it is not already done.
8320                         pkg.setPackageName(renamed);
8321                     }
8322
8323                 } else {
8324                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
8325                         if ((origPackage = mSettings.peekPackageLPr(
8326                                 pkg.mOriginalPackages.get(i))) != null) {
8327                             // We do have the package already installed under its
8328                             // original name...  should we use it?
8329                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
8330                                 // New package is not compatible with original.
8331                                 origPackage = null;
8332                                 continue;
8333                             } else if (origPackage.sharedUser != null) {
8334                                 // Make sure uid is compatible between packages.
8335                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
8336                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
8337                                             + " to " + pkg.packageName + ": old uid "
8338                                             + origPackage.sharedUser.name
8339                                             + " differs from " + pkg.mSharedUserId);
8340                                     origPackage = null;
8341                                     continue;
8342                                 }
8343                                 // TODO: Add case when shared user id is added [b/28144775]
8344                             } else {
8345                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
8346                                         + pkg.packageName + " to old name " + origPackage.name);
8347                             }
8348                             break;
8349                         }
8350                     }
8351                 }
8352             }
8353
8354             if (mTransferedPackages.contains(pkg.packageName)) {
8355                 Slog.w(TAG, "Package " + pkg.packageName
8356                         + " was transferred to another, but its .apk remains");
8357             }
8358
8359             // See comments in nonMutatedPs declaration
8360             if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8361                 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName);
8362                 if (foundPs != null) {
8363                     nonMutatedPs = new PackageSetting(foundPs);
8364                 }
8365             }
8366
8367             // Just create the setting, don't add it yet. For already existing packages
8368             // the PkgSetting exists already and doesn't have to be created.
8369             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
8370                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
8371                     pkg.applicationInfo.primaryCpuAbi,
8372                     pkg.applicationInfo.secondaryCpuAbi,
8373                     pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
8374                     user, false);
8375             if (pkgSetting == null) {
8376                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8377                         "Creating application package " + pkg.packageName + " failed");
8378             }
8379
8380             if (pkgSetting.origPackage != null) {
8381                 // If we are first transitioning from an original package,
8382                 // fix up the new package's name now.  We need to do this after
8383                 // looking up the package under its new name, so getPackageLP
8384                 // can take care of fiddling things correctly.
8385                 pkg.setPackageName(origPackage.name);
8386
8387                 // File a report about this.
8388                 String msg = "New package " + pkgSetting.realName
8389                         + " renamed to replace old package " + pkgSetting.name;
8390                 reportSettingsProblem(Log.WARN, msg);
8391
8392                 // Make a note of it.
8393                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8394                     mTransferedPackages.add(origPackage.name);
8395                 }
8396
8397                 // No longer need to retain this.
8398                 pkgSetting.origPackage = null;
8399             }
8400
8401             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
8402                 // Make a note of it.
8403                 mTransferedPackages.add(pkg.packageName);
8404             }
8405
8406             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
8407                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
8408             }
8409
8410             if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8411                 // Check all shared libraries and map to their actual file path.
8412                 // We only do this here for apps not on a system dir, because those
8413                 // are the only ones that can fail an install due to this.  We
8414                 // will take care of the system apps by updating all of their
8415                 // library paths after the scan is done.
8416                 updateSharedLibrariesLPw(pkg, null);
8417             }
8418
8419             if (mFoundPolicyFile) {
8420                 SELinuxMMAC.assignSeinfoValue(pkg);
8421             }
8422
8423             pkg.applicationInfo.uid = pkgSetting.appId;
8424             pkg.mExtras = pkgSetting;
8425             if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
8426                 if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
8427                     // We just determined the app is signed correctly, so bring
8428                     // over the latest parsed certs.
8429                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8430                 } else {
8431                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8432                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
8433                                 "Package " + pkg.packageName + " upgrade keys do not match the "
8434                                 + "previously installed version");
8435                     } else {
8436                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
8437                         String msg = "System package " + pkg.packageName
8438                             + " signature changed; retaining data.";
8439                         reportSettingsProblem(Log.WARN, msg);
8440                     }
8441                 }
8442             } else {
8443                 try {
8444                     verifySignaturesLP(pkgSetting, pkg);
8445                     // We just determined the app is signed correctly, so bring
8446                     // over the latest parsed certs.
8447                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8448                 } catch (PackageManagerException e) {
8449                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8450                         throw e;
8451                     }
8452                     // The signature has changed, but this package is in the system
8453                     // image...  let's recover!
8454                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8455                     // However...  if this package is part of a shared user, but it
8456                     // doesn't match the signature of the shared user, let's fail.
8457                     // What this means is that you can't change the signatures
8458                     // associated with an overall shared user, which doesn't seem all
8459                     // that unreasonable.
8460                     if (pkgSetting.sharedUser != null) {
8461                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8462                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
8463                             throw new PackageManagerException(
8464                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
8465                                             "Signature mismatch for shared user: "
8466                                             + pkgSetting.sharedUser);
8467                         }
8468                     }
8469                     // File a report about this.
8470                     String msg = "System package " + pkg.packageName
8471                         + " signature changed; retaining data.";
8472                     reportSettingsProblem(Log.WARN, msg);
8473                 }
8474             }
8475             // Verify that this new package doesn't have any content providers
8476             // that conflict with existing packages.  Only do this if the
8477             // package isn't already installed, since we don't want to break
8478             // things that are installed.
8479             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
8480                 final int N = pkg.providers.size();
8481                 int i;
8482                 for (i=0; i<N; i++) {
8483                     PackageParser.Provider p = pkg.providers.get(i);
8484                     if (p.info.authority != null) {
8485                         String names[] = p.info.authority.split(";");
8486                         for (int j = 0; j < names.length; j++) {
8487                             if (mProvidersByAuthority.containsKey(names[j])) {
8488                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8489                                 final String otherPackageName =
8490                                         ((other != null && other.getComponentName() != null) ?
8491                                                 other.getComponentName().getPackageName() : "?");
8492                                 throw new PackageManagerException(
8493                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
8494                                                 "Can't install because provider name " + names[j]
8495                                                 + " (in package " + pkg.applicationInfo.packageName
8496                                                 + ") is already used by " + otherPackageName);
8497                             }
8498                         }
8499                     }
8500                 }
8501             }
8502
8503             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
8504                 // This package wants to adopt ownership of permissions from
8505                 // another package.
8506                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
8507                     final String origName = pkg.mAdoptPermissions.get(i);
8508                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
8509                     if (orig != null) {
8510                         if (verifyPackageUpdateLPr(orig, pkg)) {
8511                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
8512                                     + pkg.packageName);
8513                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
8514                         }
8515                     }
8516                 }
8517             }
8518         }
8519
8520         final String pkgName = pkg.packageName;
8521
8522         final long scanFileTime = getLastModifiedTime(pkg, scanFile);
8523         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
8524         pkg.applicationInfo.processName = fixProcessName(
8525                 pkg.applicationInfo.packageName,
8526                 pkg.applicationInfo.processName,
8527                 pkg.applicationInfo.uid);
8528
8529         if (pkg != mPlatformPackage) {
8530             // Get all of our default paths setup
8531             pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
8532         }
8533
8534         final String path = scanFile.getPath();
8535         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
8536
8537         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
8538             derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
8539
8540             // Some system apps still use directory structure for native libraries
8541             // in which case we might end up not detecting abi solely based on apk
8542             // structure. Try to detect abi based on directory structure.
8543             if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
8544                     pkg.applicationInfo.primaryCpuAbi == null) {
8545                 setBundledAppAbisAndRoots(pkg, pkgSetting);
8546                 setNativeLibraryPaths(pkg);
8547             }
8548
8549         } else {
8550             if ((scanFlags & SCAN_MOVE) != 0) {
8551                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
8552                 // but we already have this packages package info in the PackageSetting. We just
8553                 // use that and derive the native library path based on the new codepath.
8554                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
8555                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
8556             }
8557
8558             // Set native library paths again. For moves, the path will be updated based on the
8559             // ABIs we've determined above. For non-moves, the path will be updated based on the
8560             // ABIs we determined during compilation, but the path will depend on the final
8561             // package path (after the rename away from the stage path).
8562             setNativeLibraryPaths(pkg);
8563         }
8564
8565         // This is a special case for the "system" package, where the ABI is
8566         // dictated by the zygote configuration (and init.rc). We should keep track
8567         // of this ABI so that we can deal with "normal" applications that run under
8568         // the same UID correctly.
8569         if (mPlatformPackage == pkg) {
8570             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
8571                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
8572         }
8573
8574         // If there's a mismatch between the abi-override in the package setting
8575         // and the abiOverride specified for the install. Warn about this because we
8576         // would've already compiled the app without taking the package setting into
8577         // account.
8578         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
8579             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
8580                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
8581                         " for package " + pkg.packageName);
8582             }
8583         }
8584
8585         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8586         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8587         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
8588
8589         // Copy the derived override back to the parsed package, so that we can
8590         // update the package settings accordingly.
8591         pkg.cpuAbiOverride = cpuAbiOverride;
8592
8593         if (DEBUG_ABI_SELECTION) {
8594             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
8595                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
8596                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
8597         }
8598
8599         // Push the derived path down into PackageSettings so we know what to
8600         // clean up at uninstall time.
8601         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
8602
8603         if (DEBUG_ABI_SELECTION) {
8604             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
8605                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
8606                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
8607         }
8608
8609         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
8610             // We don't do this here during boot because we can do it all
8611             // at once after scanning all existing packages.
8612             //
8613             // We also do this *before* we perform dexopt on this package, so that
8614             // we can avoid redundant dexopts, and also to make sure we've got the
8615             // code and package path correct.
8616             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
8617                     pkg, true /* boot complete */);
8618         }
8619
8620         if (mFactoryTest && pkg.requestedPermissions.contains(
8621                 android.Manifest.permission.FACTORY_TEST)) {
8622             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
8623         }
8624
8625         if (isSystemApp(pkg)) {
8626             pkgSetting.isOrphaned = true;
8627         }
8628
8629         ArrayList<PackageParser.Package> clientLibPkgs = null;
8630
8631         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8632             if (nonMutatedPs != null) {
8633                 synchronized (mPackages) {
8634                     mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
8635                 }
8636             }
8637             return pkg;
8638         }
8639
8640         // Only privileged apps and updated privileged apps can add child packages.
8641         if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
8642             if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
8643                 throw new PackageManagerException("Only privileged apps and updated "
8644                         + "privileged apps can add child packages. Ignoring package "
8645                         + pkg.packageName);
8646             }
8647             final int childCount = pkg.childPackages.size();
8648             for (int i = 0; i < childCount; i++) {
8649                 PackageParser.Package childPkg = pkg.childPackages.get(i);
8650                 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
8651                         childPkg.packageName)) {
8652                     throw new PackageManagerException("Cannot override a child package of "
8653                             + "another disabled system app. Ignoring package " + pkg.packageName);
8654                 }
8655             }
8656         }
8657
8658         // writer
8659         synchronized (mPackages) {
8660             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8661                 // Only system apps can add new shared libraries.
8662                 if (pkg.libraryNames != null) {
8663                     for (int i=0; i<pkg.libraryNames.size(); i++) {
8664                         String name = pkg.libraryNames.get(i);
8665                         boolean allowed = false;
8666                         if (pkg.isUpdatedSystemApp()) {
8667                             // New library entries can only be added through the
8668                             // system image.  This is important to get rid of a lot
8669                             // of nasty edge cases: for example if we allowed a non-
8670                             // system update of the app to add a library, then uninstalling
8671                             // the update would make the library go away, and assumptions
8672                             // we made such as through app install filtering would now
8673                             // have allowed apps on the device which aren't compatible
8674                             // with it.  Better to just have the restriction here, be
8675                             // conservative, and create many fewer cases that can negatively
8676                             // impact the user experience.
8677                             final PackageSetting sysPs = mSettings
8678                                     .getDisabledSystemPkgLPr(pkg.packageName);
8679                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
8680                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
8681                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
8682                                         allowed = true;
8683                                         break;
8684                                     }
8685                                 }
8686                             }
8687                         } else {
8688                             allowed = true;
8689                         }
8690                         if (allowed) {
8691                             if (!mSharedLibraries.containsKey(name)) {
8692                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
8693                             } else if (!name.equals(pkg.packageName)) {
8694                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
8695                                         + name + " already exists; skipping");
8696                             }
8697                         } else {
8698                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
8699                                     + name + " that is not declared on system image; skipping");
8700                         }
8701                     }
8702                     if ((scanFlags & SCAN_BOOTING) == 0) {
8703                         // If we are not booting, we need to update any applications
8704                         // that are clients of our shared library.  If we are booting,
8705                         // this will all be done once the scan is complete.
8706                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
8707                     }
8708                 }
8709             }
8710         }
8711
8712         if ((scanFlags & SCAN_BOOTING) != 0) {
8713             // No apps can run during boot scan, so they don't need to be frozen
8714         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
8715             // Caller asked to not kill app, so it's probably not frozen
8716         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
8717             // Caller asked us to ignore frozen check for some reason; they
8718             // probably didn't know the package name
8719         } else {
8720             // We're doing major surgery on this package, so it better be frozen
8721             // right now to keep it from launching
8722             checkPackageFrozen(pkgName);
8723         }
8724
8725         // Also need to kill any apps that are dependent on the library.
8726         if (clientLibPkgs != null) {
8727             for (int i=0; i<clientLibPkgs.size(); i++) {
8728                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
8729                 killApplication(clientPkg.applicationInfo.packageName,
8730                         clientPkg.applicationInfo.uid, "update lib");
8731             }
8732         }
8733
8734         // Make sure we're not adding any bogus keyset info
8735         KeySetManagerService ksms = mSettings.mKeySetManagerService;
8736         ksms.assertScannedPackageValid(pkg);
8737
8738         // writer
8739         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
8740
8741         boolean createIdmapFailed = false;
8742         synchronized (mPackages) {
8743             // We don't expect installation to fail beyond this point
8744
8745             if (pkgSetting.pkg != null) {
8746                 // Note that |user| might be null during the initial boot scan. If a codePath
8747                 // for an app has changed during a boot scan, it's due to an app update that's
8748                 // part of the system partition and marker changes must be applied to all users.
8749                 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg,
8750                     (user != null) ? user : UserHandle.ALL);
8751             }
8752
8753             // Add the new setting to mSettings
8754             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
8755             // Add the new setting to mPackages
8756             mPackages.put(pkg.applicationInfo.packageName, pkg);
8757             // Make sure we don't accidentally delete its data.
8758             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
8759             while (iter.hasNext()) {
8760                 PackageCleanItem item = iter.next();
8761                 if (pkgName.equals(item.packageName)) {
8762                     iter.remove();
8763                 }
8764             }
8765
8766             // Take care of first install / last update times.
8767             if (currentTime != 0) {
8768                 if (pkgSetting.firstInstallTime == 0) {
8769                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
8770                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
8771                     pkgSetting.lastUpdateTime = currentTime;
8772                 }
8773             } else if (pkgSetting.firstInstallTime == 0) {
8774                 // We need *something*.  Take time time stamp of the file.
8775                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
8776             } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
8777                 if (scanFileTime != pkgSetting.timeStamp) {
8778                     // A package on the system image has changed; consider this
8779                     // to be an update.
8780                     pkgSetting.lastUpdateTime = scanFileTime;
8781                 }
8782             }
8783
8784             // Add the package's KeySets to the global KeySetManagerService
8785             ksms.addScannedPackageLPw(pkg);
8786
8787             int N = pkg.providers.size();
8788             StringBuilder r = null;
8789             int i;
8790             for (i=0; i<N; i++) {
8791                 PackageParser.Provider p = pkg.providers.get(i);
8792                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
8793                         p.info.processName, pkg.applicationInfo.uid);
8794                 mProviders.addProvider(p);
8795                 p.syncable = p.info.isSyncable;
8796                 if (p.info.authority != null) {
8797                     String names[] = p.info.authority.split(";");
8798                     p.info.authority = null;
8799                     for (int j = 0; j < names.length; j++) {
8800                         if (j == 1 && p.syncable) {
8801                             // We only want the first authority for a provider to possibly be
8802                             // syncable, so if we already added this provider using a different
8803                             // authority clear the syncable flag. We copy the provider before
8804                             // changing it because the mProviders object contains a reference
8805                             // to a provider that we don't want to change.
8806                             // Only do this for the second authority since the resulting provider
8807                             // object can be the same for all future authorities for this provider.
8808                             p = new PackageParser.Provider(p);
8809                             p.syncable = false;
8810                         }
8811                         if (!mProvidersByAuthority.containsKey(names[j])) {
8812                             mProvidersByAuthority.put(names[j], p);
8813                             if (p.info.authority == null) {
8814                                 p.info.authority = names[j];
8815                             } else {
8816                                 p.info.authority = p.info.authority + ";" + names[j];
8817                             }
8818                             if (DEBUG_PACKAGE_SCANNING) {
8819                                 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8820                                     Log.d(TAG, "Registered content provider: " + names[j]
8821                                             + ", className = " + p.info.name + ", isSyncable = "
8822                                             + p.info.isSyncable);
8823                             }
8824                         } else {
8825                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8826                             Slog.w(TAG, "Skipping provider name " + names[j] +
8827                                     " (in package " + pkg.applicationInfo.packageName +
8828                                     "): name already used by "
8829                                     + ((other != null && other.getComponentName() != null)
8830                                             ? other.getComponentName().getPackageName() : "?"));
8831                         }
8832                     }
8833                 }
8834                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8835                     if (r == null) {
8836                         r = new StringBuilder(256);
8837                     } else {
8838                         r.append(' ');
8839                     }
8840                     r.append(p.info.name);
8841                 }
8842             }
8843             if (r != null) {
8844                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
8845             }
8846
8847             N = pkg.services.size();
8848             r = null;
8849             for (i=0; i<N; i++) {
8850                 PackageParser.Service s = pkg.services.get(i);
8851                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
8852                         s.info.processName, pkg.applicationInfo.uid);
8853                 mServices.addService(s);
8854                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8855                     if (r == null) {
8856                         r = new StringBuilder(256);
8857                     } else {
8858                         r.append(' ');
8859                     }
8860                     r.append(s.info.name);
8861                 }
8862             }
8863             if (r != null) {
8864                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
8865             }
8866
8867             N = pkg.receivers.size();
8868             r = null;
8869             for (i=0; i<N; i++) {
8870                 PackageParser.Activity a = pkg.receivers.get(i);
8871                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8872                         a.info.processName, pkg.applicationInfo.uid);
8873                 mReceivers.addActivity(a, "receiver");
8874                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8875                     if (r == null) {
8876                         r = new StringBuilder(256);
8877                     } else {
8878                         r.append(' ');
8879                     }
8880                     r.append(a.info.name);
8881                 }
8882             }
8883             if (r != null) {
8884                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
8885             }
8886
8887             N = pkg.activities.size();
8888             r = null;
8889             for (i=0; i<N; i++) {
8890                 PackageParser.Activity a = pkg.activities.get(i);
8891                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8892                         a.info.processName, pkg.applicationInfo.uid);
8893                 mActivities.addActivity(a, "activity");
8894                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8895                     if (r == null) {
8896                         r = new StringBuilder(256);
8897                     } else {
8898                         r.append(' ');
8899                     }
8900                     r.append(a.info.name);
8901                 }
8902             }
8903             if (r != null) {
8904                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
8905             }
8906
8907             N = pkg.permissionGroups.size();
8908             r = null;
8909             for (i=0; i<N; i++) {
8910                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
8911                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
8912                 final String curPackageName = cur == null ? null : cur.info.packageName;
8913                 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
8914                 if (cur == null || isPackageUpdate) {
8915                     mPermissionGroups.put(pg.info.name, pg);
8916                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8917                         if (r == null) {
8918                             r = new StringBuilder(256);
8919                         } else {
8920                             r.append(' ');
8921                         }
8922                         if (isPackageUpdate) {
8923                             r.append("UPD:");
8924                         }
8925                         r.append(pg.info.name);
8926                     }
8927                 } else {
8928                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
8929                             + pg.info.packageName + " ignored: original from "
8930                             + cur.info.packageName);
8931                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8932                         if (r == null) {
8933                             r = new StringBuilder(256);
8934                         } else {
8935                             r.append(' ');
8936                         }
8937                         r.append("DUP:");
8938                         r.append(pg.info.name);
8939                     }
8940                 }
8941             }
8942             if (r != null) {
8943                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
8944             }
8945
8946             N = pkg.permissions.size();
8947             r = null;
8948             for (i=0; i<N; i++) {
8949                 PackageParser.Permission p = pkg.permissions.get(i);
8950
8951                 // Assume by default that we did not install this permission into the system.
8952                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
8953
8954                 // Now that permission groups have a special meaning, we ignore permission
8955                 // groups for legacy apps to prevent unexpected behavior. In particular,
8956                 // permissions for one app being granted to someone just becase they happen
8957                 // to be in a group defined by another app (before this had no implications).
8958                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
8959                     p.group = mPermissionGroups.get(p.info.group);
8960                     // Warn for a permission in an unknown group.
8961                     if (p.info.group != null && p.group == null) {
8962                         Slog.w(TAG, "Permission " + p.info.name + " from package "
8963                                 + p.info.packageName + " in an unknown group " + p.info.group);
8964                     }
8965                 }
8966
8967                 ArrayMap<String, BasePermission> permissionMap =
8968                         p.tree ? mSettings.mPermissionTrees
8969                                 : mSettings.mPermissions;
8970                 BasePermission bp = permissionMap.get(p.info.name);
8971
8972                 // Allow system apps to redefine non-system permissions
8973                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
8974                     final boolean currentOwnerIsSystem = (bp.perm != null
8975                             && isSystemApp(bp.perm.owner));
8976                     if (isSystemApp(p.owner)) {
8977                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
8978                             // It's a built-in permission and no owner, take ownership now
8979                             bp.packageSetting = pkgSetting;
8980                             bp.perm = p;
8981                             bp.uid = pkg.applicationInfo.uid;
8982                             bp.sourcePackage = p.info.packageName;
8983                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8984                         } else if (!currentOwnerIsSystem) {
8985                             String msg = "New decl " + p.owner + " of permission  "
8986                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
8987                             reportSettingsProblem(Log.WARN, msg);
8988                             bp = null;
8989                         }
8990                     }
8991                 }
8992
8993                 if (bp == null) {
8994                     bp = new BasePermission(p.info.name, p.info.packageName,
8995                             BasePermission.TYPE_NORMAL);
8996                     permissionMap.put(p.info.name, bp);
8997                 }
8998
8999                 if (bp.perm == null) {
9000                     if (bp.sourcePackage == null
9001                             || bp.sourcePackage.equals(p.info.packageName)) {
9002                         BasePermission tree = findPermissionTreeLP(p.info.name);
9003                         if (tree == null
9004                                 || tree.sourcePackage.equals(p.info.packageName)) {
9005                             bp.packageSetting = pkgSetting;
9006                             bp.perm = p;
9007                             bp.uid = pkg.applicationInfo.uid;
9008                             bp.sourcePackage = p.info.packageName;
9009                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
9010                             if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
9011                                 if (r == null) {
9012                                     r = new StringBuilder(256);
9013                                 } else {
9014                                     r.append(' ');
9015                                 }
9016                                 r.append(p.info.name);
9017                             }
9018                         } else {
9019                             Slog.w(TAG, "Permission " + p.info.name + " from package "
9020                                     + p.info.packageName + " ignored: base tree "
9021                                     + tree.name + " is from package "
9022                                     + tree.sourcePackage);
9023                         }
9024                     } else {
9025                         Slog.w(TAG, "Permission " + p.info.name + " from package "
9026                                 + p.info.packageName + " ignored: original from "
9027                                 + bp.sourcePackage);
9028                     }
9029                 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
9030                     if (r == null) {
9031                         r = new StringBuilder(256);
9032                     } else {
9033                         r.append(' ');
9034                     }
9035                     r.append("DUP:");
9036                     r.append(p.info.name);
9037                 }
9038                 if (bp.perm == p) {
9039                     bp.protectionLevel = p.info.protectionLevel;
9040                 }
9041             }
9042
9043             if (r != null) {
9044                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
9045             }
9046
9047             N = pkg.instrumentation.size();
9048             r = null;
9049             for (i=0; i<N; i++) {
9050                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
9051                 a.info.packageName = pkg.applicationInfo.packageName;
9052                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
9053                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
9054                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
9055                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
9056                 a.info.dataDir = pkg.applicationInfo.dataDir;
9057                 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
9058                 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
9059
9060                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
9061                 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
9062                 mInstrumentation.put(a.getComponentName(), a);
9063                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
9064                     if (r == null) {
9065                         r = new StringBuilder(256);
9066                     } else {
9067                         r.append(' ');
9068                     }
9069                     r.append(a.info.name);
9070                 }
9071             }
9072             if (r != null) {
9073                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
9074             }
9075
9076             if (pkg.protectedBroadcasts != null) {
9077                 N = pkg.protectedBroadcasts.size();
9078                 for (i=0; i<N; i++) {
9079                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
9080                 }
9081             }
9082
9083             pkgSetting.setTimeStamp(scanFileTime);
9084
9085             // Create idmap files for pairs of (packages, overlay packages).
9086             // Note: "android", ie framework-res.apk, is handled by native layers.
9087             if (pkg.mOverlayTarget != null) {
9088                 // This is an overlay package.
9089                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
9090                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
9091                         mOverlays.put(pkg.mOverlayTarget,
9092                                 new ArrayMap<String, PackageParser.Package>());
9093                     }
9094                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
9095                     map.put(pkg.packageName, pkg);
9096                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
9097                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
9098                         createIdmapFailed = true;
9099                     }
9100                 }
9101             } else if (mOverlays.containsKey(pkg.packageName) &&
9102                     !pkg.packageName.equals("android")) {
9103                 // This is a regular package, with one or more known overlay packages.
9104                 createIdmapsForPackageLI(pkg);
9105             }
9106
9107             if (oldPkg != null) {
9108                 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
9109                 // revokation from this method might need to kill apps which need the
9110                 // mPackages lock on a different thread. This would dead lock.
9111                 //
9112                 // Hence create a copy of all package names and pass it into
9113                 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
9114                 // revoked. If a new package is added before the async code runs the permission
9115                 // won't be granted yet, hence new packages are no problem.
9116                 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
9117
9118                 AsyncTask.execute(new Runnable() {
9119                     public void run() {
9120                         revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames);
9121                     }
9122                 });
9123             }
9124         }
9125
9126         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9127
9128         if (createIdmapFailed) {
9129             throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9130                     "scanPackageLI failed to createIdmap");
9131         }
9132         return pkg;
9133     }
9134
9135     private void maybeRenameForeignDexMarkers(PackageParser.Package existing,
9136             PackageParser.Package update, UserHandle user) {
9137         if (existing.applicationInfo == null || update.applicationInfo == null) {
9138             // This isn't due to an app installation.
9139             return;
9140         }
9141
9142         final File oldCodePath = new File(existing.applicationInfo.getCodePath());
9143         final File newCodePath = new File(update.applicationInfo.getCodePath());
9144
9145         // The codePath hasn't changed, so there's nothing for us to do.
9146         if (Objects.equals(oldCodePath, newCodePath)) {
9147             return;
9148         }
9149
9150         File canonicalNewCodePath;
9151         try {
9152             canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath));
9153         } catch (IOException e) {
9154             Slog.w(TAG, "Failed to get canonical path.", e);
9155             return;
9156         }
9157
9158         // This is a bit of a hack. The oldCodePath doesn't exist at this point (because
9159         // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume
9160         // that the last component of the path (i.e, the name) doesn't need canonicalization
9161         // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now
9162         // but may change in the future. Hopefully this function won't exist at that point.
9163         final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(),
9164                 oldCodePath.getName());
9165
9166         // Calculate the prefixes of the markers. These are just the paths with "/" replaced
9167         // with "@".
9168         String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@');
9169         if (!oldMarkerPrefix.endsWith("@")) {
9170             oldMarkerPrefix += "@";
9171         }
9172         String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@');
9173         if (!newMarkerPrefix.endsWith("@")) {
9174             newMarkerPrefix += "@";
9175         }
9176
9177         List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly();
9178         List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size());
9179         for (String updatedPath : updatedPaths) {
9180             String updatedPathName = new File(updatedPath).getName();
9181             markerSuffixes.add(updatedPathName.replace('/', '@'));
9182         }
9183
9184         for (int userId : resolveUserIds(user.getIdentifier())) {
9185             File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId);
9186
9187             for (String markerSuffix : markerSuffixes) {
9188                 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix);
9189                 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix);
9190                 if (oldForeignUseMark.exists()) {
9191                     try {
9192                         Os.rename(oldForeignUseMark.getAbsolutePath(),
9193                                 newForeignUseMark.getAbsolutePath());
9194                     } catch (ErrnoException e) {
9195                         Slog.w(TAG, "Failed to rename foreign use marker", e);
9196                         oldForeignUseMark.delete();
9197                     }
9198                 }
9199             }
9200         }
9201     }
9202
9203     /**
9204      * Derive the ABI of a non-system package located at {@code scanFile}. This information
9205      * is derived purely on the basis of the contents of {@code scanFile} and
9206      * {@code cpuAbiOverride}.
9207      *
9208      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
9209      */
9210     private void derivePackageAbi(PackageParser.Package pkg, File scanFile,
9211                                  String cpuAbiOverride, boolean extractLibs)
9212             throws PackageManagerException {
9213         // TODO: We can probably be smarter about this stuff. For installed apps,
9214         // we can calculate this information at install time once and for all. For
9215         // system apps, we can probably assume that this information doesn't change
9216         // after the first boot scan. As things stand, we do lots of unnecessary work.
9217
9218         // Give ourselves some initial paths; we'll come back for another
9219         // pass once we've determined ABI below.
9220         setNativeLibraryPaths(pkg);
9221
9222         // We would never need to extract libs for forward-locked and external packages,
9223         // since the container service will do it for us. We shouldn't attempt to
9224         // extract libs from system app when it was not updated.
9225         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
9226                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
9227             extractLibs = false;
9228         }
9229
9230         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
9231         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
9232
9233         NativeLibraryHelper.Handle handle = null;
9234         try {
9235             handle = NativeLibraryHelper.Handle.create(pkg);
9236             // TODO(multiArch): This can be null for apps that didn't go through the
9237             // usual installation process. We can calculate it again, like we
9238             // do during install time.
9239             //
9240             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
9241             // unnecessary.
9242             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
9243
9244             // Null out the abis so that they can be recalculated.
9245             pkg.applicationInfo.primaryCpuAbi = null;
9246             pkg.applicationInfo.secondaryCpuAbi = null;
9247             if (isMultiArch(pkg.applicationInfo)) {
9248                 // Warn if we've set an abiOverride for multi-lib packages..
9249                 // By definition, we need to copy both 32 and 64 bit libraries for
9250                 // such packages.
9251                 if (pkg.cpuAbiOverride != null
9252                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
9253                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
9254                 }
9255
9256                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
9257                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
9258                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
9259                     if (extractLibs) {
9260                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9261                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
9262                                 useIsaSpecificSubdirs);
9263                     } else {
9264                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
9265                     }
9266                 }
9267
9268                 maybeThrowExceptionForMultiArchCopy(
9269                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
9270
9271                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
9272                     if (extractLibs) {
9273                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9274                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
9275                                 useIsaSpecificSubdirs);
9276                     } else {
9277                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
9278                     }
9279                 }
9280
9281                 maybeThrowExceptionForMultiArchCopy(
9282                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
9283
9284                 if (abi64 >= 0) {
9285                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
9286                 }
9287
9288                 if (abi32 >= 0) {
9289                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
9290                     if (abi64 >= 0) {
9291                         if (pkg.use32bitAbi) {
9292                             pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
9293                             pkg.applicationInfo.primaryCpuAbi = abi;
9294                         } else {
9295                             pkg.applicationInfo.secondaryCpuAbi = abi;
9296                         }
9297                     } else {
9298                         pkg.applicationInfo.primaryCpuAbi = abi;
9299                     }
9300                 }
9301
9302             } else {
9303                 String[] abiList = (cpuAbiOverride != null) ?
9304                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
9305
9306                 // Enable gross and lame hacks for apps that are built with old
9307                 // SDK tools. We must scan their APKs for renderscript bitcode and
9308                 // not launch them if it's present. Don't bother checking on devices
9309                 // that don't have 64 bit support.
9310                 boolean needsRenderScriptOverride = false;
9311                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
9312                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
9313                     abiList = Build.SUPPORTED_32_BIT_ABIS;
9314                     needsRenderScriptOverride = true;
9315                 }
9316
9317                 final int copyRet;
9318                 if (extractLibs) {
9319                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9320                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
9321                 } else {
9322                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
9323                 }
9324
9325                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
9326                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
9327                             "Error unpackaging native libs for app, errorCode=" + copyRet);
9328                 }
9329
9330                 if (copyRet >= 0) {
9331                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
9332                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
9333                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
9334                 } else if (needsRenderScriptOverride) {
9335                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
9336                 }
9337             }
9338         } catch (IOException ioe) {
9339             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
9340         } finally {
9341             IoUtils.closeQuietly(handle);
9342         }
9343
9344         // Now that we've calculated the ABIs and determined if it's an internal app,
9345         // we will go ahead and populate the nativeLibraryPath.
9346         setNativeLibraryPaths(pkg);
9347     }
9348
9349     /**
9350      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
9351      * i.e, so that all packages can be run inside a single process if required.
9352      *
9353      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
9354      * this function will either try and make the ABI for all packages in {@code packagesForUser}
9355      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
9356      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
9357      * updating a package that belongs to a shared user.
9358      *
9359      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
9360      * adds unnecessary complexity.
9361      */
9362     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
9363             PackageParser.Package scannedPackage, boolean bootComplete) {
9364         String requiredInstructionSet = null;
9365         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
9366             requiredInstructionSet = VMRuntime.getInstructionSet(
9367                      scannedPackage.applicationInfo.primaryCpuAbi);
9368         }
9369
9370         PackageSetting requirer = null;
9371         for (PackageSetting ps : packagesForUser) {
9372             // If packagesForUser contains scannedPackage, we skip it. This will happen
9373             // when scannedPackage is an update of an existing package. Without this check,
9374             // we will never be able to change the ABI of any package belonging to a shared
9375             // user, even if it's compatible with other packages.
9376             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9377                 if (ps.primaryCpuAbiString == null) {
9378                     continue;
9379                 }
9380
9381                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
9382                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
9383                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
9384                     // this but there's not much we can do.
9385                     String errorMessage = "Instruction set mismatch, "
9386                             + ((requirer == null) ? "[caller]" : requirer)
9387                             + " requires " + requiredInstructionSet + " whereas " + ps
9388                             + " requires " + instructionSet;
9389                     Slog.w(TAG, errorMessage);
9390                 }
9391
9392                 if (requiredInstructionSet == null) {
9393                     requiredInstructionSet = instructionSet;
9394                     requirer = ps;
9395                 }
9396             }
9397         }
9398
9399         if (requiredInstructionSet != null) {
9400             String adjustedAbi;
9401             if (requirer != null) {
9402                 // requirer != null implies that either scannedPackage was null or that scannedPackage
9403                 // did not require an ABI, in which case we have to adjust scannedPackage to match
9404                 // the ABI of the set (which is the same as requirer's ABI)
9405                 adjustedAbi = requirer.primaryCpuAbiString;
9406                 if (scannedPackage != null) {
9407                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
9408                 }
9409             } else {
9410                 // requirer == null implies that we're updating all ABIs in the set to
9411                 // match scannedPackage.
9412                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
9413             }
9414
9415             for (PackageSetting ps : packagesForUser) {
9416                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9417                     if (ps.primaryCpuAbiString != null) {
9418                         continue;
9419                     }
9420
9421                     ps.primaryCpuAbiString = adjustedAbi;
9422                     if (ps.pkg != null && ps.pkg.applicationInfo != null &&
9423                             !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
9424                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
9425                         Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
9426                                 + " (requirer="
9427                                 + (requirer == null ? "null" : requirer.pkg.packageName)
9428                                 + ", scannedPackage="
9429                                 + (scannedPackage != null ? scannedPackage.packageName : "null")
9430                                 + ")");
9431                         try {
9432                             mInstaller.rmdex(ps.codePathString,
9433                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
9434                         } catch (InstallerException ignored) {
9435                         }
9436                     }
9437                 }
9438             }
9439         }
9440     }
9441
9442     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
9443         synchronized (mPackages) {
9444             mResolverReplaced = true;
9445             // Set up information for custom user intent resolution activity.
9446             mResolveActivity.applicationInfo = pkg.applicationInfo;
9447             mResolveActivity.name = mCustomResolverComponentName.getClassName();
9448             mResolveActivity.packageName = pkg.applicationInfo.packageName;
9449             mResolveActivity.processName = pkg.applicationInfo.packageName;
9450             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9451             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
9452                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9453             mResolveActivity.theme = 0;
9454             mResolveActivity.exported = true;
9455             mResolveActivity.enabled = true;
9456             mResolveInfo.activityInfo = mResolveActivity;
9457             mResolveInfo.priority = 0;
9458             mResolveInfo.preferredOrder = 0;
9459             mResolveInfo.match = 0;
9460             mResolveComponentName = mCustomResolverComponentName;
9461             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
9462                     mResolveComponentName);
9463         }
9464     }
9465
9466     private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
9467         final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
9468
9469         // Set up information for ephemeral installer activity
9470         mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
9471         mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
9472         mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
9473         mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
9474         mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9475         mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
9476                 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9477         mEphemeralInstallerActivity.theme = 0;
9478         mEphemeralInstallerActivity.exported = true;
9479         mEphemeralInstallerActivity.enabled = true;
9480         mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
9481         mEphemeralInstallerInfo.priority = 0;
9482         mEphemeralInstallerInfo.preferredOrder = 1;
9483         mEphemeralInstallerInfo.isDefault = true;
9484         mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
9485                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
9486
9487         if (DEBUG_EPHEMERAL) {
9488             Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
9489         }
9490     }
9491
9492     private static String calculateBundledApkRoot(final String codePathString) {
9493         final File codePath = new File(codePathString);
9494         final File codeRoot;
9495         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
9496             codeRoot = Environment.getRootDirectory();
9497         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
9498             codeRoot = Environment.getOemDirectory();
9499         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
9500             codeRoot = Environment.getVendorDirectory();
9501         } else {
9502             // Unrecognized code path; take its top real segment as the apk root:
9503             // e.g. /something/app/blah.apk => /something
9504             try {
9505                 File f = codePath.getCanonicalFile();
9506                 File parent = f.getParentFile();    // non-null because codePath is a file
9507                 File tmp;
9508                 while ((tmp = parent.getParentFile()) != null) {
9509                     f = parent;
9510                     parent = tmp;
9511                 }
9512                 codeRoot = f;
9513                 Slog.w(TAG, "Unrecognized code path "
9514                         + codePath + " - using " + codeRoot);
9515             } catch (IOException e) {
9516                 // Can't canonicalize the code path -- shenanigans?
9517                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
9518                 return Environment.getRootDirectory().getPath();
9519             }
9520         }
9521         return codeRoot.getPath();
9522     }
9523
9524     /**
9525      * Derive and set the location of native libraries for the given package,
9526      * which varies depending on where and how the package was installed.
9527      */
9528     private void setNativeLibraryPaths(PackageParser.Package pkg) {
9529         final ApplicationInfo info = pkg.applicationInfo;
9530         final String codePath = pkg.codePath;
9531         final File codeFile = new File(codePath);
9532         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
9533         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
9534
9535         info.nativeLibraryRootDir = null;
9536         info.nativeLibraryRootRequiresIsa = false;
9537         info.nativeLibraryDir = null;
9538         info.secondaryNativeLibraryDir = null;
9539
9540         if (isApkFile(codeFile)) {
9541             // Monolithic install
9542             if (bundledApp) {
9543                 // If "/system/lib64/apkname" exists, assume that is the per-package
9544                 // native library directory to use; otherwise use "/system/lib/apkname".
9545                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
9546                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
9547                         getPrimaryInstructionSet(info));
9548
9549                 // This is a bundled system app so choose the path based on the ABI.
9550                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
9551                 // is just the default path.
9552                 final String apkName = deriveCodePathName(codePath);
9553                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
9554                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
9555                         apkName).getAbsolutePath();
9556
9557                 if (info.secondaryCpuAbi != null) {
9558                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
9559                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
9560                             secondaryLibDir, apkName).getAbsolutePath();
9561                 }
9562             } else if (asecApp) {
9563                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
9564                         .getAbsolutePath();
9565             } else {
9566                 final String apkName = deriveCodePathName(codePath);
9567                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
9568                         .getAbsolutePath();
9569             }
9570
9571             info.nativeLibraryRootRequiresIsa = false;
9572             info.nativeLibraryDir = info.nativeLibraryRootDir;
9573         } else {
9574             // Cluster install
9575             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
9576             info.nativeLibraryRootRequiresIsa = true;
9577
9578             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
9579                     getPrimaryInstructionSet(info)).getAbsolutePath();
9580
9581             if (info.secondaryCpuAbi != null) {
9582                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
9583                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
9584             }
9585         }
9586     }
9587
9588     /**
9589      * Calculate the abis and roots for a bundled app. These can uniquely
9590      * be determined from the contents of the system partition, i.e whether
9591      * it contains 64 or 32 bit shared libraries etc. We do not validate any
9592      * of this information, and instead assume that the system was built
9593      * sensibly.
9594      */
9595     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
9596                                            PackageSetting pkgSetting) {
9597         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
9598
9599         // If "/system/lib64/apkname" exists, assume that is the per-package
9600         // native library directory to use; otherwise use "/system/lib/apkname".
9601         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
9602         setBundledAppAbi(pkg, apkRoot, apkName);
9603         // pkgSetting might be null during rescan following uninstall of updates
9604         // to a bundled app, so accommodate that possibility.  The settings in
9605         // that case will be established later from the parsed package.
9606         //
9607         // If the settings aren't null, sync them up with what we've just derived.
9608         // note that apkRoot isn't stored in the package settings.
9609         if (pkgSetting != null) {
9610             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9611             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9612         }
9613     }
9614
9615     /**
9616      * Deduces the ABI of a bundled app and sets the relevant fields on the
9617      * parsed pkg object.
9618      *
9619      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
9620      *        under which system libraries are installed.
9621      * @param apkName the name of the installed package.
9622      */
9623     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
9624         final File codeFile = new File(pkg.codePath);
9625
9626         final boolean has64BitLibs;
9627         final boolean has32BitLibs;
9628         if (isApkFile(codeFile)) {
9629             // Monolithic install
9630             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
9631             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
9632         } else {
9633             // Cluster install
9634             final File rootDir = new File(codeFile, LIB_DIR_NAME);
9635             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
9636                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
9637                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
9638                 has64BitLibs = (new File(rootDir, isa)).exists();
9639             } else {
9640                 has64BitLibs = false;
9641             }
9642             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
9643                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
9644                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
9645                 has32BitLibs = (new File(rootDir, isa)).exists();
9646             } else {
9647                 has32BitLibs = false;
9648             }
9649         }
9650
9651         if (has64BitLibs && !has32BitLibs) {
9652             // The package has 64 bit libs, but not 32 bit libs. Its primary
9653             // ABI should be 64 bit. We can safely assume here that the bundled
9654             // native libraries correspond to the most preferred ABI in the list.
9655
9656             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9657             pkg.applicationInfo.secondaryCpuAbi = null;
9658         } else if (has32BitLibs && !has64BitLibs) {
9659             // The package has 32 bit libs but not 64 bit libs. Its primary
9660             // ABI should be 32 bit.
9661
9662             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9663             pkg.applicationInfo.secondaryCpuAbi = null;
9664         } else if (has32BitLibs && has64BitLibs) {
9665             // The application has both 64 and 32 bit bundled libraries. We check
9666             // here that the app declares multiArch support, and warn if it doesn't.
9667             //
9668             // We will be lenient here and record both ABIs. The primary will be the
9669             // ABI that's higher on the list, i.e, a device that's configured to prefer
9670             // 64 bit apps will see a 64 bit primary ABI,
9671
9672             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
9673                 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
9674             }
9675
9676             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
9677                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9678                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9679             } else {
9680                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9681                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9682             }
9683         } else {
9684             pkg.applicationInfo.primaryCpuAbi = null;
9685             pkg.applicationInfo.secondaryCpuAbi = null;
9686         }
9687     }
9688
9689     private void killApplication(String pkgName, int appId, String reason) {
9690         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
9691     }
9692
9693     private void killApplication(String pkgName, int appId, int userId, String reason) {
9694         // Request the ActivityManager to kill the process(only for existing packages)
9695         // so that we do not end up in a confused state while the user is still using the older
9696         // version of the application while the new one gets installed.
9697         final long token = Binder.clearCallingIdentity();
9698         try {
9699             IActivityManager am = ActivityManagerNative.getDefault();
9700             if (am != null) {
9701                 try {
9702                     am.killApplication(pkgName, appId, userId, reason);
9703                 } catch (RemoteException e) {
9704                 }
9705             }
9706         } finally {
9707             Binder.restoreCallingIdentity(token);
9708         }
9709     }
9710
9711     private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
9712         // Remove the parent package setting
9713         PackageSetting ps = (PackageSetting) pkg.mExtras;
9714         if (ps != null) {
9715             removePackageLI(ps, chatty);
9716         }
9717         // Remove the child package setting
9718         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9719         for (int i = 0; i < childCount; i++) {
9720             PackageParser.Package childPkg = pkg.childPackages.get(i);
9721             ps = (PackageSetting) childPkg.mExtras;
9722             if (ps != null) {
9723                 removePackageLI(ps, chatty);
9724             }
9725         }
9726     }
9727
9728     void removePackageLI(PackageSetting ps, boolean chatty) {
9729         if (DEBUG_INSTALL) {
9730             if (chatty)
9731                 Log.d(TAG, "Removing package " + ps.name);
9732         }
9733
9734         // writer
9735         synchronized (mPackages) {
9736             mPackages.remove(ps.name);
9737             final PackageParser.Package pkg = ps.pkg;
9738             if (pkg != null) {
9739                 cleanPackageDataStructuresLILPw(pkg, chatty);
9740             }
9741         }
9742     }
9743
9744     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
9745         if (DEBUG_INSTALL) {
9746             if (chatty)
9747                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
9748         }
9749
9750         // writer
9751         synchronized (mPackages) {
9752             // Remove the parent package
9753             mPackages.remove(pkg.applicationInfo.packageName);
9754             cleanPackageDataStructuresLILPw(pkg, chatty);
9755
9756             // Remove the child packages
9757             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9758             for (int i = 0; i < childCount; i++) {
9759                 PackageParser.Package childPkg = pkg.childPackages.get(i);
9760                 mPackages.remove(childPkg.applicationInfo.packageName);
9761                 cleanPackageDataStructuresLILPw(childPkg, chatty);
9762             }
9763         }
9764     }
9765
9766     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
9767         int N = pkg.providers.size();
9768         StringBuilder r = null;
9769         int i;
9770         for (i=0; i<N; i++) {
9771             PackageParser.Provider p = pkg.providers.get(i);
9772             mProviders.removeProvider(p);
9773             if (p.info.authority == null) {
9774
9775                 /* There was another ContentProvider with this authority when
9776                  * this app was installed so this authority is null,
9777                  * Ignore it as we don't have to unregister the provider.
9778                  */
9779                 continue;
9780             }
9781             String names[] = p.info.authority.split(";");
9782             for (int j = 0; j < names.length; j++) {
9783                 if (mProvidersByAuthority.get(names[j]) == p) {
9784                     mProvidersByAuthority.remove(names[j]);
9785                     if (DEBUG_REMOVE) {
9786                         if (chatty)
9787                             Log.d(TAG, "Unregistered content provider: " + names[j]
9788                                     + ", className = " + p.info.name + ", isSyncable = "
9789                                     + p.info.isSyncable);
9790                     }
9791                 }
9792             }
9793             if (DEBUG_REMOVE && chatty) {
9794                 if (r == null) {
9795                     r = new StringBuilder(256);
9796                 } else {
9797                     r.append(' ');
9798                 }
9799                 r.append(p.info.name);
9800             }
9801         }
9802         if (r != null) {
9803             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
9804         }
9805
9806         N = pkg.services.size();
9807         r = null;
9808         for (i=0; i<N; i++) {
9809             PackageParser.Service s = pkg.services.get(i);
9810             mServices.removeService(s);
9811             if (chatty) {
9812                 if (r == null) {
9813                     r = new StringBuilder(256);
9814                 } else {
9815                     r.append(' ');
9816                 }
9817                 r.append(s.info.name);
9818             }
9819         }
9820         if (r != null) {
9821             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
9822         }
9823
9824         N = pkg.receivers.size();
9825         r = null;
9826         for (i=0; i<N; i++) {
9827             PackageParser.Activity a = pkg.receivers.get(i);
9828             mReceivers.removeActivity(a, "receiver");
9829             if (DEBUG_REMOVE && chatty) {
9830                 if (r == null) {
9831                     r = new StringBuilder(256);
9832                 } else {
9833                     r.append(' ');
9834                 }
9835                 r.append(a.info.name);
9836             }
9837         }
9838         if (r != null) {
9839             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
9840         }
9841
9842         N = pkg.activities.size();
9843         r = null;
9844         for (i=0; i<N; i++) {
9845             PackageParser.Activity a = pkg.activities.get(i);
9846             mActivities.removeActivity(a, "activity");
9847             if (DEBUG_REMOVE && chatty) {
9848                 if (r == null) {
9849                     r = new StringBuilder(256);
9850                 } else {
9851                     r.append(' ');
9852                 }
9853                 r.append(a.info.name);
9854             }
9855         }
9856         if (r != null) {
9857             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
9858         }
9859
9860         N = pkg.permissions.size();
9861         r = null;
9862         for (i=0; i<N; i++) {
9863             PackageParser.Permission p = pkg.permissions.get(i);
9864             BasePermission bp = mSettings.mPermissions.get(p.info.name);
9865             if (bp == null) {
9866                 bp = mSettings.mPermissionTrees.get(p.info.name);
9867             }
9868             if (bp != null && bp.perm == p) {
9869                 bp.perm = null;
9870                 if (DEBUG_REMOVE && chatty) {
9871                     if (r == null) {
9872                         r = new StringBuilder(256);
9873                     } else {
9874                         r.append(' ');
9875                     }
9876                     r.append(p.info.name);
9877                 }
9878             }
9879             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9880                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
9881                 if (appOpPkgs != null) {
9882                     appOpPkgs.remove(pkg.packageName);
9883                 }
9884             }
9885         }
9886         if (r != null) {
9887             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9888         }
9889
9890         N = pkg.requestedPermissions.size();
9891         r = null;
9892         for (i=0; i<N; i++) {
9893             String perm = pkg.requestedPermissions.get(i);
9894             BasePermission bp = mSettings.mPermissions.get(perm);
9895             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9896                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
9897                 if (appOpPkgs != null) {
9898                     appOpPkgs.remove(pkg.packageName);
9899                     if (appOpPkgs.isEmpty()) {
9900                         mAppOpPermissionPackages.remove(perm);
9901                     }
9902                 }
9903             }
9904         }
9905         if (r != null) {
9906             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9907         }
9908
9909         N = pkg.instrumentation.size();
9910         r = null;
9911         for (i=0; i<N; i++) {
9912             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
9913             mInstrumentation.remove(a.getComponentName());
9914             if (DEBUG_REMOVE && chatty) {
9915                 if (r == null) {
9916                     r = new StringBuilder(256);
9917                 } else {
9918                     r.append(' ');
9919                 }
9920                 r.append(a.info.name);
9921             }
9922         }
9923         if (r != null) {
9924             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
9925         }
9926
9927         r = null;
9928         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9929             // Only system apps can hold shared libraries.
9930             if (pkg.libraryNames != null) {
9931                 for (i=0; i<pkg.libraryNames.size(); i++) {
9932                     String name = pkg.libraryNames.get(i);
9933                     SharedLibraryEntry cur = mSharedLibraries.get(name);
9934                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
9935                         mSharedLibraries.remove(name);
9936                         if (DEBUG_REMOVE && chatty) {
9937                             if (r == null) {
9938                                 r = new StringBuilder(256);
9939                             } else {
9940                                 r.append(' ');
9941                             }
9942                             r.append(name);
9943                         }
9944                     }
9945                 }
9946             }
9947         }
9948         if (r != null) {
9949             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
9950         }
9951     }
9952
9953     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
9954         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
9955             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
9956                 return true;
9957             }
9958         }
9959         return false;
9960     }
9961
9962     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
9963     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
9964     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
9965
9966     private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
9967         // Update the parent permissions
9968         updatePermissionsLPw(pkg.packageName, pkg, flags);
9969         // Update the child permissions
9970         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9971         for (int i = 0; i < childCount; i++) {
9972             PackageParser.Package childPkg = pkg.childPackages.get(i);
9973             updatePermissionsLPw(childPkg.packageName, childPkg, flags);
9974         }
9975     }
9976
9977     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
9978             int flags) {
9979         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
9980         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
9981     }
9982
9983     private void updatePermissionsLPw(String changingPkg,
9984             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
9985         // Make sure there are no dangling permission trees.
9986         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
9987         while (it.hasNext()) {
9988             final BasePermission bp = it.next();
9989             if (bp.packageSetting == null) {
9990                 // We may not yet have parsed the package, so just see if
9991                 // we still know about its settings.
9992                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9993             }
9994             if (bp.packageSetting == null) {
9995                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
9996                         + " from package " + bp.sourcePackage);
9997                 it.remove();
9998             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9999                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
10000                     Slog.i(TAG, "Removing old permission tree: " + bp.name
10001                             + " from package " + bp.sourcePackage);
10002                     flags |= UPDATE_PERMISSIONS_ALL;
10003                     it.remove();
10004                 }
10005             }
10006         }
10007
10008         // Make sure all dynamic permissions have been assigned to a package,
10009         // and make sure there are no dangling permissions.
10010         it = mSettings.mPermissions.values().iterator();
10011         while (it.hasNext()) {
10012             final BasePermission bp = it.next();
10013             if (bp.type == BasePermission.TYPE_DYNAMIC) {
10014                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
10015                         + bp.name + " pkg=" + bp.sourcePackage
10016                         + " info=" + bp.pendingInfo);
10017                 if (bp.packageSetting == null && bp.pendingInfo != null) {
10018                     final BasePermission tree = findPermissionTreeLP(bp.name);
10019                     if (tree != null && tree.perm != null) {
10020                         bp.packageSetting = tree.packageSetting;
10021                         bp.perm = new PackageParser.Permission(tree.perm.owner,
10022                                 new PermissionInfo(bp.pendingInfo));
10023                         bp.perm.info.packageName = tree.perm.info.packageName;
10024                         bp.perm.info.name = bp.name;
10025                         bp.uid = tree.uid;
10026                     }
10027                 }
10028             }
10029             if (bp.packageSetting == null) {
10030                 // We may not yet have parsed the package, so just see if
10031                 // we still know about its settings.
10032                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
10033             }
10034             if (bp.packageSetting == null) {
10035                 Slog.w(TAG, "Removing dangling permission: " + bp.name
10036                         + " from package " + bp.sourcePackage);
10037                 it.remove();
10038             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
10039                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
10040                     Slog.i(TAG, "Removing old permission: " + bp.name
10041                             + " from package " + bp.sourcePackage);
10042                     flags |= UPDATE_PERMISSIONS_ALL;
10043                     it.remove();
10044                 }
10045             }
10046         }
10047
10048         // Now update the permissions for all packages, in particular
10049         // replace the granted permissions of the system packages.
10050         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
10051             for (PackageParser.Package pkg : mPackages.values()) {
10052                 if (pkg != pkgInfo) {
10053                     // Only replace for packages on requested volume
10054                     final String volumeUuid = getVolumeUuidForPackage(pkg);
10055                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
10056                             && Objects.equals(replaceVolumeUuid, volumeUuid);
10057                     grantPermissionsLPw(pkg, replace, changingPkg);
10058                 }
10059             }
10060         }
10061
10062         if (pkgInfo != null) {
10063             // Only replace for packages on requested volume
10064             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
10065             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
10066                     && Objects.equals(replaceVolumeUuid, volumeUuid);
10067             grantPermissionsLPw(pkgInfo, replace, changingPkg);
10068         }
10069     }
10070
10071     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
10072             String packageOfInterest) {
10073         // IMPORTANT: There are two types of permissions: install and runtime.
10074         // Install time permissions are granted when the app is installed to
10075         // all device users and users added in the future. Runtime permissions
10076         // are granted at runtime explicitly to specific users. Normal and signature
10077         // protected permissions are install time permissions. Dangerous permissions
10078         // are install permissions if the app's target SDK is Lollipop MR1 or older,
10079         // otherwise they are runtime permissions. This function does not manage
10080         // runtime permissions except for the case an app targeting Lollipop MR1
10081         // being upgraded to target a newer SDK, in which case dangerous permissions
10082         // are transformed from install time to runtime ones.
10083
10084         final PackageSetting ps = (PackageSetting) pkg.mExtras;
10085         if (ps == null) {
10086             return;
10087         }
10088
10089         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
10090
10091         PermissionsState permissionsState = ps.getPermissionsState();
10092         PermissionsState origPermissions = permissionsState;
10093
10094         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
10095
10096         boolean runtimePermissionsRevoked = false;
10097         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
10098
10099         boolean changedInstallPermission = false;
10100
10101         if (replace) {
10102             ps.installPermissionsFixed = false;
10103             if (!ps.isSharedUser()) {
10104                 origPermissions = new PermissionsState(permissionsState);
10105                 permissionsState.reset();
10106             } else {
10107                 // We need to know only about runtime permission changes since the
10108                 // calling code always writes the install permissions state but
10109                 // the runtime ones are written only if changed. The only cases of
10110                 // changed runtime permissions here are promotion of an install to
10111                 // runtime and revocation of a runtime from a shared user.
10112                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
10113                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
10114                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
10115                     runtimePermissionsRevoked = true;
10116                 }
10117             }
10118         }
10119
10120         permissionsState.setGlobalGids(mGlobalGids);
10121
10122         final int N = pkg.requestedPermissions.size();
10123         for (int i=0; i<N; i++) {
10124             final String name = pkg.requestedPermissions.get(i);
10125             final BasePermission bp = mSettings.mPermissions.get(name);
10126
10127             if (DEBUG_INSTALL) {
10128                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
10129             }
10130
10131             if (bp == null || bp.packageSetting == null) {
10132                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
10133                     Slog.w(TAG, "Unknown permission " + name
10134                             + " in package " + pkg.packageName);
10135                 }
10136                 continue;
10137             }
10138
10139             final String perm = bp.name;
10140             boolean allowedSig = false;
10141             int grant = GRANT_DENIED;
10142
10143             // Keep track of app op permissions.
10144             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
10145                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
10146                 if (pkgs == null) {
10147                     pkgs = new ArraySet<>();
10148                     mAppOpPermissionPackages.put(bp.name, pkgs);
10149                 }
10150                 pkgs.add(pkg.packageName);
10151             }
10152
10153             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
10154             final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
10155                     >= Build.VERSION_CODES.M;
10156             switch (level) {
10157                 case PermissionInfo.PROTECTION_NORMAL: {
10158                     // For all apps normal permissions are install time ones.
10159                     grant = GRANT_INSTALL;
10160                 } break;
10161
10162                 case PermissionInfo.PROTECTION_DANGEROUS: {
10163                     // If a permission review is required for legacy apps we represent
10164                     // their permissions as always granted runtime ones since we need
10165                     // to keep the review required permission flag per user while an
10166                     // install permission's state is shared across all users.
10167                     if (!appSupportsRuntimePermissions && !mPermissionReviewRequired
10168                             && !Build.PERMISSIONS_REVIEW_REQUIRED) {
10169                         // For legacy apps dangerous permissions are install time ones.
10170                         grant = GRANT_INSTALL;
10171                     } else if (origPermissions.hasInstallPermission(bp.name)) {
10172                         // For legacy apps that became modern, install becomes runtime.
10173                         grant = GRANT_UPGRADE;
10174                     } else if (mPromoteSystemApps
10175                             && isSystemApp(ps)
10176                             && mExistingSystemPackages.contains(ps.name)) {
10177                         // For legacy system apps, install becomes runtime.
10178                         // We cannot check hasInstallPermission() for system apps since those
10179                         // permissions were granted implicitly and not persisted pre-M.
10180                         grant = GRANT_UPGRADE;
10181                     } else {
10182                         // For modern apps keep runtime permissions unchanged.
10183                         grant = GRANT_RUNTIME;
10184                     }
10185                 } break;
10186
10187                 case PermissionInfo.PROTECTION_SIGNATURE: {
10188                     // For all apps signature permissions are install time ones.
10189                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
10190                     if (allowedSig) {
10191                         grant = GRANT_INSTALL;
10192                     }
10193                 } break;
10194             }
10195
10196             if (DEBUG_INSTALL) {
10197                 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
10198             }
10199
10200             if (grant != GRANT_DENIED) {
10201                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
10202                     // If this is an existing, non-system package, then
10203                     // we can't add any new permissions to it.
10204                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
10205                         // Except...  if this is a permission that was added
10206                         // to the platform (note: need to only do this when
10207                         // updating the platform).
10208                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
10209                             grant = GRANT_DENIED;
10210                         }
10211                     }
10212                 }
10213
10214                 switch (grant) {
10215                     case GRANT_INSTALL: {
10216                         // Revoke this as runtime permission to handle the case of
10217                         // a runtime permission being downgraded to an install one.
10218                         // Also in permission review mode we keep dangerous permissions
10219                         // for legacy apps
10220                         for (int userId : UserManagerService.getInstance().getUserIds()) {
10221                             if (origPermissions.getRuntimePermissionState(
10222                                     bp.name, userId) != null) {
10223                                 // Revoke the runtime permission and clear the flags.
10224                                 origPermissions.revokeRuntimePermission(bp, userId);
10225                                 origPermissions.updatePermissionFlags(bp, userId,
10226                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
10227                                 // If we revoked a permission permission, we have to write.
10228                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10229                                         changedRuntimePermissionUserIds, userId);
10230                             }
10231                         }
10232                         // Grant an install permission.
10233                         if (permissionsState.grantInstallPermission(bp) !=
10234                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
10235                             changedInstallPermission = true;
10236                         }
10237                     } break;
10238
10239                     case GRANT_RUNTIME: {
10240                         // Grant previously granted runtime permissions.
10241                         for (int userId : UserManagerService.getInstance().getUserIds()) {
10242                             PermissionState permissionState = origPermissions
10243                                     .getRuntimePermissionState(bp.name, userId);
10244                             int flags = permissionState != null
10245                                     ? permissionState.getFlags() : 0;
10246                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
10247                                 // Don't propagate the permission in a permission review mode if
10248                                 // the former was revoked, i.e. marked to not propagate on upgrade.
10249                                 // Note that in a permission review mode install permissions are
10250                                 // represented as constantly granted runtime ones since we need to
10251                                 // keep a per user state associated with the permission. Also the
10252                                 // revoke on upgrade flag is no longer applicable and is reset.
10253                                 final boolean revokeOnUpgrade = (flags & PackageManager
10254                                         .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
10255                                 if (revokeOnUpgrade) {
10256                                     flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
10257                                     // Since we changed the flags, we have to write.
10258                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10259                                             changedRuntimePermissionUserIds, userId);
10260                                 }
10261                                 if (!mPermissionReviewRequired || !revokeOnUpgrade) {
10262                                     if (permissionsState.grantRuntimePermission(bp, userId) ==
10263                                             PermissionsState.PERMISSION_OPERATION_FAILURE) {
10264                                         // If we cannot put the permission as it was,
10265                                         // we have to write.
10266                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10267                                                 changedRuntimePermissionUserIds, userId);
10268                                     }
10269                                 }
10270
10271                                 // If the app supports runtime permissions no need for a review.
10272                                 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
10273                                         && appSupportsRuntimePermissions
10274                                         && (flags & PackageManager
10275                                                 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
10276                                     flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
10277                                     // Since we changed the flags, we have to write.
10278                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10279                                             changedRuntimePermissionUserIds, userId);
10280                                 }
10281                             } else if ((mPermissionReviewRequired
10282                                         || Build.PERMISSIONS_REVIEW_REQUIRED)
10283                                     && !appSupportsRuntimePermissions) {
10284                                 // For legacy apps that need a permission review, every new
10285                                 // runtime permission is granted but it is pending a review.
10286                                 // We also need to review only platform defined runtime
10287                                 // permissions as these are the only ones the platform knows
10288                                 // how to disable the API to simulate revocation as legacy
10289                                 // apps don't expect to run with revoked permissions.
10290                                 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
10291                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
10292                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
10293                                         // We changed the flags, hence have to write.
10294                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10295                                                 changedRuntimePermissionUserIds, userId);
10296                                     }
10297                                 }
10298                                 if (permissionsState.grantRuntimePermission(bp, userId)
10299                                         != PermissionsState.PERMISSION_OPERATION_FAILURE) {
10300                                     // We changed the permission, hence have to write.
10301                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10302                                             changedRuntimePermissionUserIds, userId);
10303                                 }
10304                             }
10305                             // Propagate the permission flags.
10306                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
10307                         }
10308                     } break;
10309
10310                     case GRANT_UPGRADE: {
10311                         // Grant runtime permissions for a previously held install permission.
10312                         PermissionState permissionState = origPermissions
10313                                 .getInstallPermissionState(bp.name);
10314                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
10315
10316                         if (origPermissions.revokeInstallPermission(bp)
10317                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
10318                             // We will be transferring the permission flags, so clear them.
10319                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
10320                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
10321                             changedInstallPermission = true;
10322                         }
10323
10324                         // If the permission is not to be promoted to runtime we ignore it and
10325                         // also its other flags as they are not applicable to install permissions.
10326                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
10327                             for (int userId : currentUserIds) {
10328                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
10329                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
10330                                     // Transfer the permission flags.
10331                                     permissionsState.updatePermissionFlags(bp, userId,
10332                                             flags, flags);
10333                                     // If we granted the permission, we have to write.
10334                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10335                                             changedRuntimePermissionUserIds, userId);
10336                                 }
10337                             }
10338                         }
10339                     } break;
10340
10341                     default: {
10342                         if (packageOfInterest == null
10343                                 || packageOfInterest.equals(pkg.packageName)) {
10344                             Slog.w(TAG, "Not granting permission " + perm
10345                                     + " to package " + pkg.packageName
10346                                     + " because it was previously installed without");
10347                         }
10348                     } break;
10349                 }
10350             } else {
10351                 if (permissionsState.revokeInstallPermission(bp) !=
10352                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
10353                     // Also drop the permission flags.
10354                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
10355                             PackageManager.MASK_PERMISSION_FLAGS, 0);
10356                     changedInstallPermission = true;
10357                     Slog.i(TAG, "Un-granting permission " + perm
10358                             + " from package " + pkg.packageName
10359                             + " (protectionLevel=" + bp.protectionLevel
10360                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10361                             + ")");
10362                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
10363                     // Don't print warning for app op permissions, since it is fine for them
10364                     // not to be granted, there is a UI for the user to decide.
10365                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
10366                         Slog.w(TAG, "Not granting permission " + perm
10367                                 + " to package " + pkg.packageName
10368                                 + " (protectionLevel=" + bp.protectionLevel
10369                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10370                                 + ")");
10371                     }
10372                 }
10373             }
10374         }
10375
10376         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
10377                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
10378             // This is the first that we have heard about this package, so the
10379             // permissions we have now selected are fixed until explicitly
10380             // changed.
10381             ps.installPermissionsFixed = true;
10382         }
10383
10384         // Persist the runtime permissions state for users with changes. If permissions
10385         // were revoked because no app in the shared user declares them we have to
10386         // write synchronously to avoid losing runtime permissions state.
10387         for (int userId : changedRuntimePermissionUserIds) {
10388             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
10389         }
10390
10391         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10392     }
10393
10394     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
10395         boolean allowed = false;
10396         final int NP = PackageParser.NEW_PERMISSIONS.length;
10397         for (int ip=0; ip<NP; ip++) {
10398             final PackageParser.NewPermissionInfo npi
10399                     = PackageParser.NEW_PERMISSIONS[ip];
10400             if (npi.name.equals(perm)
10401                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
10402                 allowed = true;
10403                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
10404                         + pkg.packageName);
10405                 break;
10406             }
10407         }
10408         return allowed;
10409     }
10410
10411     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
10412             BasePermission bp, PermissionsState origPermissions) {
10413         boolean allowed;
10414         allowed = (compareSignatures(
10415                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
10416                         == PackageManager.SIGNATURE_MATCH)
10417                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
10418                         == PackageManager.SIGNATURE_MATCH);
10419         if (!allowed && (bp.protectionLevel
10420                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
10421             if (isSystemApp(pkg)) {
10422                 // For updated system applications, a system permission
10423                 // is granted only if it had been defined by the original application.
10424                 if (pkg.isUpdatedSystemApp()) {
10425                     final PackageSetting sysPs = mSettings
10426                             .getDisabledSystemPkgLPr(pkg.packageName);
10427                     if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
10428                         // If the original was granted this permission, we take
10429                         // that grant decision as read and propagate it to the
10430                         // update.
10431                         if (sysPs.isPrivileged()) {
10432                             allowed = true;
10433                         }
10434                     } else {
10435                         // The system apk may have been updated with an older
10436                         // version of the one on the data partition, but which
10437                         // granted a new system permission that it didn't have
10438                         // before.  In this case we do want to allow the app to
10439                         // now get the new permission if the ancestral apk is
10440                         // privileged to get it.
10441                         if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
10442                             for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
10443                                 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
10444                                     allowed = true;
10445                                     break;
10446                                 }
10447                             }
10448                         }
10449                         // Also if a privileged parent package on the system image or any of
10450                         // its children requested a privileged permission, the updated child
10451                         // packages can also get the permission.
10452                         if (pkg.parentPackage != null) {
10453                             final PackageSetting disabledSysParentPs = mSettings
10454                                     .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
10455                             if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
10456                                     && disabledSysParentPs.isPrivileged()) {
10457                                 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
10458                                     allowed = true;
10459                                 } else if (disabledSysParentPs.pkg.childPackages != null) {
10460                                     final int count = disabledSysParentPs.pkg.childPackages.size();
10461                                     for (int i = 0; i < count; i++) {
10462                                         PackageParser.Package disabledSysChildPkg =
10463                                                 disabledSysParentPs.pkg.childPackages.get(i);
10464                                         if (isPackageRequestingPermission(disabledSysChildPkg,
10465                                                 perm)) {
10466                                             allowed = true;
10467                                             break;
10468                                         }
10469                                     }
10470                                 }
10471                             }
10472                         }
10473                     }
10474                 } else {
10475                     allowed = isPrivilegedApp(pkg);
10476                 }
10477             }
10478         }
10479         if (!allowed) {
10480             if (!allowed && (bp.protectionLevel
10481                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
10482                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
10483                 // If this was a previously normal/dangerous permission that got moved
10484                 // to a system permission as part of the runtime permission redesign, then
10485                 // we still want to blindly grant it to old apps.
10486                 allowed = true;
10487             }
10488             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
10489                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
10490                 // If this permission is to be granted to the system installer and
10491                 // this app is an installer, then it gets the permission.
10492                 allowed = true;
10493             }
10494             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
10495                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
10496                 // If this permission is to be granted to the system verifier and
10497                 // this app is a verifier, then it gets the permission.
10498                 allowed = true;
10499             }
10500             if (!allowed && (bp.protectionLevel
10501                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
10502                     && isSystemApp(pkg)) {
10503                 // Any pre-installed system app is allowed to get this permission.
10504                 allowed = true;
10505             }
10506             if (!allowed && (bp.protectionLevel
10507                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
10508                 // For development permissions, a development permission
10509                 // is granted only if it was already granted.
10510                 allowed = origPermissions.hasInstallPermission(perm);
10511             }
10512             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
10513                     && pkg.packageName.equals(mSetupWizardPackage)) {
10514                 // If this permission is to be granted to the system setup wizard and
10515                 // this app is a setup wizard, then it gets the permission.
10516                 allowed = true;
10517             }
10518         }
10519         return allowed;
10520     }
10521
10522     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
10523         final int permCount = pkg.requestedPermissions.size();
10524         for (int j = 0; j < permCount; j++) {
10525             String requestedPermission = pkg.requestedPermissions.get(j);
10526             if (permission.equals(requestedPermission)) {
10527                 return true;
10528             }
10529         }
10530         return false;
10531     }
10532
10533     final class ActivityIntentResolver
10534             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
10535         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10536                 boolean defaultOnly, int userId) {
10537             if (!sUserManager.exists(userId)) return null;
10538             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10539             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10540         }
10541
10542         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10543                 int userId) {
10544             if (!sUserManager.exists(userId)) return null;
10545             mFlags = flags;
10546             return super.queryIntent(intent, resolvedType,
10547                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10548         }
10549
10550         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10551                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
10552             if (!sUserManager.exists(userId)) return null;
10553             if (packageActivities == null) {
10554                 return null;
10555             }
10556             mFlags = flags;
10557             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
10558             final int N = packageActivities.size();
10559             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
10560                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
10561
10562             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
10563             for (int i = 0; i < N; ++i) {
10564                 intentFilters = packageActivities.get(i).intents;
10565                 if (intentFilters != null && intentFilters.size() > 0) {
10566                     PackageParser.ActivityIntentInfo[] array =
10567                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
10568                     intentFilters.toArray(array);
10569                     listCut.add(array);
10570                 }
10571             }
10572             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
10573         }
10574
10575         /**
10576          * Finds a privileged activity that matches the specified activity names.
10577          */
10578         private PackageParser.Activity findMatchingActivity(
10579                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
10580             for (PackageParser.Activity sysActivity : activityList) {
10581                 if (sysActivity.info.name.equals(activityInfo.name)) {
10582                     return sysActivity;
10583                 }
10584                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
10585                     return sysActivity;
10586                 }
10587                 if (sysActivity.info.targetActivity != null) {
10588                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
10589                         return sysActivity;
10590                     }
10591                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
10592                         return sysActivity;
10593                     }
10594                 }
10595             }
10596             return null;
10597         }
10598
10599         public class IterGenerator<E> {
10600             public Iterator<E> generate(ActivityIntentInfo info) {
10601                 return null;
10602             }
10603         }
10604
10605         public class ActionIterGenerator extends IterGenerator<String> {
10606             @Override
10607             public Iterator<String> generate(ActivityIntentInfo info) {
10608                 return info.actionsIterator();
10609             }
10610         }
10611
10612         public class CategoriesIterGenerator extends IterGenerator<String> {
10613             @Override
10614             public Iterator<String> generate(ActivityIntentInfo info) {
10615                 return info.categoriesIterator();
10616             }
10617         }
10618
10619         public class SchemesIterGenerator extends IterGenerator<String> {
10620             @Override
10621             public Iterator<String> generate(ActivityIntentInfo info) {
10622                 return info.schemesIterator();
10623             }
10624         }
10625
10626         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
10627             @Override
10628             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
10629                 return info.authoritiesIterator();
10630             }
10631         }
10632
10633         /**
10634          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
10635          * MODIFIED. Do not pass in a list that should not be changed.
10636          */
10637         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
10638                 IterGenerator<T> generator, Iterator<T> searchIterator) {
10639             // loop through the set of actions; every one must be found in the intent filter
10640             while (searchIterator.hasNext()) {
10641                 // we must have at least one filter in the list to consider a match
10642                 if (intentList.size() == 0) {
10643                     break;
10644                 }
10645
10646                 final T searchAction = searchIterator.next();
10647
10648                 // loop through the set of intent filters
10649                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
10650                 while (intentIter.hasNext()) {
10651                     final ActivityIntentInfo intentInfo = intentIter.next();
10652                     boolean selectionFound = false;
10653
10654                     // loop through the intent filter's selection criteria; at least one
10655                     // of them must match the searched criteria
10656                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
10657                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
10658                         final T intentSelection = intentSelectionIter.next();
10659                         if (intentSelection != null && intentSelection.equals(searchAction)) {
10660                             selectionFound = true;
10661                             break;
10662                         }
10663                     }
10664
10665                     // the selection criteria wasn't found in this filter's set; this filter
10666                     // is not a potential match
10667                     if (!selectionFound) {
10668                         intentIter.remove();
10669                     }
10670                 }
10671             }
10672         }
10673
10674         private boolean isProtectedAction(ActivityIntentInfo filter) {
10675             final Iterator<String> actionsIter = filter.actionsIterator();
10676             while (actionsIter != null && actionsIter.hasNext()) {
10677                 final String filterAction = actionsIter.next();
10678                 if (PROTECTED_ACTIONS.contains(filterAction)) {
10679                     return true;
10680                 }
10681             }
10682             return false;
10683         }
10684
10685         /**
10686          * Adjusts the priority of the given intent filter according to policy.
10687          * <p>
10688          * <ul>
10689          * <li>The priority for non privileged applications is capped to '0'</li>
10690          * <li>The priority for protected actions on privileged applications is capped to '0'</li>
10691          * <li>The priority for unbundled updates to privileged applications is capped to the
10692          *      priority defined on the system partition</li>
10693          * </ul>
10694          * <p>
10695          * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
10696          * allowed to obtain any priority on any action.
10697          */
10698         private void adjustPriority(
10699                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
10700             // nothing to do; priority is fine as-is
10701             if (intent.getPriority() <= 0) {
10702                 return;
10703             }
10704
10705             final ActivityInfo activityInfo = intent.activity.info;
10706             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
10707
10708             final boolean privilegedApp =
10709                     ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
10710             if (!privilegedApp) {
10711                 // non-privileged applications can never define a priority >0
10712                 Slog.w(TAG, "Non-privileged app; cap priority to 0;"
10713                         + " package: " + applicationInfo.packageName
10714                         + " activity: " + intent.activity.className
10715                         + " origPrio: " + intent.getPriority());
10716                 intent.setPriority(0);
10717                 return;
10718             }
10719
10720             if (systemActivities == null) {
10721                 // the system package is not disabled; we're parsing the system partition
10722                 if (isProtectedAction(intent)) {
10723                     if (mDeferProtectedFilters) {
10724                         // We can't deal with these just yet. No component should ever obtain a
10725                         // >0 priority for a protected actions, with ONE exception -- the setup
10726                         // wizard. The setup wizard, however, cannot be known until we're able to
10727                         // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
10728                         // until all intent filters have been processed. Chicken, meet egg.
10729                         // Let the filter temporarily have a high priority and rectify the
10730                         // priorities after all system packages have been scanned.
10731                         mProtectedFilters.add(intent);
10732                         if (DEBUG_FILTERS) {
10733                             Slog.i(TAG, "Protected action; save for later;"
10734                                     + " package: " + applicationInfo.packageName
10735                                     + " activity: " + intent.activity.className
10736                                     + " origPrio: " + intent.getPriority());
10737                         }
10738                         return;
10739                     } else {
10740                         if (DEBUG_FILTERS && mSetupWizardPackage == null) {
10741                             Slog.i(TAG, "No setup wizard;"
10742                                 + " All protected intents capped to priority 0");
10743                         }
10744                         if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
10745                             if (DEBUG_FILTERS) {
10746                                 Slog.i(TAG, "Found setup wizard;"
10747                                     + " allow priority " + intent.getPriority() + ";"
10748                                     + " package: " + intent.activity.info.packageName
10749                                     + " activity: " + intent.activity.className
10750                                     + " priority: " + intent.getPriority());
10751                             }
10752                             // setup wizard gets whatever it wants
10753                             return;
10754                         }
10755                         Slog.w(TAG, "Protected action; cap priority to 0;"
10756                                 + " package: " + intent.activity.info.packageName
10757                                 + " activity: " + intent.activity.className
10758                                 + " origPrio: " + intent.getPriority());
10759                         intent.setPriority(0);
10760                         return;
10761                     }
10762                 }
10763                 // privileged apps on the system image get whatever priority they request
10764                 return;
10765             }
10766
10767             // privileged app unbundled update ... try to find the same activity
10768             final PackageParser.Activity foundActivity =
10769                     findMatchingActivity(systemActivities, activityInfo);
10770             if (foundActivity == null) {
10771                 // this is a new activity; it cannot obtain >0 priority
10772                 if (DEBUG_FILTERS) {
10773                     Slog.i(TAG, "New activity; cap priority to 0;"
10774                             + " package: " + applicationInfo.packageName
10775                             + " activity: " + intent.activity.className
10776                             + " origPrio: " + intent.getPriority());
10777                 }
10778                 intent.setPriority(0);
10779                 return;
10780             }
10781
10782             // found activity, now check for filter equivalence
10783
10784             // a shallow copy is enough; we modify the list, not its contents
10785             final List<ActivityIntentInfo> intentListCopy =
10786                     new ArrayList<>(foundActivity.intents);
10787             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
10788
10789             // find matching action subsets
10790             final Iterator<String> actionsIterator = intent.actionsIterator();
10791             if (actionsIterator != null) {
10792                 getIntentListSubset(
10793                         intentListCopy, new ActionIterGenerator(), actionsIterator);
10794                 if (intentListCopy.size() == 0) {
10795                     // no more intents to match; we're not equivalent
10796                     if (DEBUG_FILTERS) {
10797                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
10798                                 + " package: " + applicationInfo.packageName
10799                                 + " activity: " + intent.activity.className
10800                                 + " origPrio: " + intent.getPriority());
10801                     }
10802                     intent.setPriority(0);
10803                     return;
10804                 }
10805             }
10806
10807             // find matching category subsets
10808             final Iterator<String> categoriesIterator = intent.categoriesIterator();
10809             if (categoriesIterator != null) {
10810                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
10811                         categoriesIterator);
10812                 if (intentListCopy.size() == 0) {
10813                     // no more intents to match; we're not equivalent
10814                     if (DEBUG_FILTERS) {
10815                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
10816                                 + " package: " + applicationInfo.packageName
10817                                 + " activity: " + intent.activity.className
10818                                 + " origPrio: " + intent.getPriority());
10819                     }
10820                     intent.setPriority(0);
10821                     return;
10822                 }
10823             }
10824
10825             // find matching schemes subsets
10826             final Iterator<String> schemesIterator = intent.schemesIterator();
10827             if (schemesIterator != null) {
10828                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
10829                         schemesIterator);
10830                 if (intentListCopy.size() == 0) {
10831                     // no more intents to match; we're not equivalent
10832                     if (DEBUG_FILTERS) {
10833                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
10834                                 + " package: " + applicationInfo.packageName
10835                                 + " activity: " + intent.activity.className
10836                                 + " origPrio: " + intent.getPriority());
10837                     }
10838                     intent.setPriority(0);
10839                     return;
10840                 }
10841             }
10842
10843             // find matching authorities subsets
10844             final Iterator<IntentFilter.AuthorityEntry>
10845                     authoritiesIterator = intent.authoritiesIterator();
10846             if (authoritiesIterator != null) {
10847                 getIntentListSubset(intentListCopy,
10848                         new AuthoritiesIterGenerator(),
10849                         authoritiesIterator);
10850                 if (intentListCopy.size() == 0) {
10851                     // no more intents to match; we're not equivalent
10852                     if (DEBUG_FILTERS) {
10853                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
10854                                 + " package: " + applicationInfo.packageName
10855                                 + " activity: " + intent.activity.className
10856                                 + " origPrio: " + intent.getPriority());
10857                     }
10858                     intent.setPriority(0);
10859                     return;
10860                 }
10861             }
10862
10863             // we found matching filter(s); app gets the max priority of all intents
10864             int cappedPriority = 0;
10865             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
10866                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
10867             }
10868             if (intent.getPriority() > cappedPriority) {
10869                 if (DEBUG_FILTERS) {
10870                     Slog.i(TAG, "Found matching filter(s);"
10871                             + " cap priority to " + cappedPriority + ";"
10872                             + " package: " + applicationInfo.packageName
10873                             + " activity: " + intent.activity.className
10874                             + " origPrio: " + intent.getPriority());
10875                 }
10876                 intent.setPriority(cappedPriority);
10877                 return;
10878             }
10879             // all this for nothing; the requested priority was <= what was on the system
10880         }
10881
10882         public final void addActivity(PackageParser.Activity a, String type) {
10883             mActivities.put(a.getComponentName(), a);
10884             if (DEBUG_SHOW_INFO)
10885                 Log.v(
10886                 TAG, "  " + type + " " +
10887                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
10888             if (DEBUG_SHOW_INFO)
10889                 Log.v(TAG, "    Class=" + a.info.name);
10890             final int NI = a.intents.size();
10891             for (int j=0; j<NI; j++) {
10892                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10893                 if ("activity".equals(type)) {
10894                     final PackageSetting ps =
10895                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
10896                     final List<PackageParser.Activity> systemActivities =
10897                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
10898                     adjustPriority(systemActivities, intent);
10899                 }
10900                 if (DEBUG_SHOW_INFO) {
10901                     Log.v(TAG, "    IntentFilter:");
10902                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10903                 }
10904                 if (!intent.debugCheck()) {
10905                     Log.w(TAG, "==> For Activity " + a.info.name);
10906                 }
10907                 addFilter(intent);
10908             }
10909         }
10910
10911         public final void removeActivity(PackageParser.Activity a, String type) {
10912             mActivities.remove(a.getComponentName());
10913             if (DEBUG_SHOW_INFO) {
10914                 Log.v(TAG, "  " + type + " "
10915                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
10916                                 : a.info.name) + ":");
10917                 Log.v(TAG, "    Class=" + a.info.name);
10918             }
10919             final int NI = a.intents.size();
10920             for (int j=0; j<NI; j++) {
10921                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10922                 if (DEBUG_SHOW_INFO) {
10923                     Log.v(TAG, "    IntentFilter:");
10924                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10925                 }
10926                 removeFilter(intent);
10927             }
10928         }
10929
10930         @Override
10931         protected boolean allowFilterResult(
10932                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
10933             ActivityInfo filterAi = filter.activity.info;
10934             for (int i=dest.size()-1; i>=0; i--) {
10935                 ActivityInfo destAi = dest.get(i).activityInfo;
10936                 if (destAi.name == filterAi.name
10937                         && destAi.packageName == filterAi.packageName) {
10938                     return false;
10939                 }
10940             }
10941             return true;
10942         }
10943
10944         @Override
10945         protected ActivityIntentInfo[] newArray(int size) {
10946             return new ActivityIntentInfo[size];
10947         }
10948
10949         @Override
10950         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
10951             if (!sUserManager.exists(userId)) return true;
10952             PackageParser.Package p = filter.activity.owner;
10953             if (p != null) {
10954                 PackageSetting ps = (PackageSetting)p.mExtras;
10955                 if (ps != null) {
10956                     // System apps are never considered stopped for purposes of
10957                     // filtering, because there may be no way for the user to
10958                     // actually re-launch them.
10959                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
10960                             && ps.getStopped(userId);
10961                 }
10962             }
10963             return false;
10964         }
10965
10966         @Override
10967         protected boolean isPackageForFilter(String packageName,
10968                 PackageParser.ActivityIntentInfo info) {
10969             return packageName.equals(info.activity.owner.packageName);
10970         }
10971
10972         @Override
10973         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
10974                 int match, int userId) {
10975             if (!sUserManager.exists(userId)) return null;
10976             if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
10977                 return null;
10978             }
10979             final PackageParser.Activity activity = info.activity;
10980             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
10981             if (ps == null) {
10982                 return null;
10983             }
10984             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
10985                     ps.readUserState(userId), userId);
10986             if (ai == null) {
10987                 return null;
10988             }
10989             final ResolveInfo res = new ResolveInfo();
10990             res.activityInfo = ai;
10991             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
10992                 res.filter = info;
10993             }
10994             if (info != null) {
10995                 res.handleAllWebDataURI = info.handleAllWebDataURI();
10996             }
10997             res.priority = info.getPriority();
10998             res.preferredOrder = activity.owner.mPreferredOrder;
10999             //System.out.println("Result: " + res.activityInfo.className +
11000             //                   " = " + res.priority);
11001             res.match = match;
11002             res.isDefault = info.hasDefault;
11003             res.labelRes = info.labelRes;
11004             res.nonLocalizedLabel = info.nonLocalizedLabel;
11005             if (userNeedsBadging(userId)) {
11006                 res.noResourceId = true;
11007             } else {
11008                 res.icon = info.icon;
11009             }
11010             res.iconResourceId = info.icon;
11011             res.system = res.activityInfo.applicationInfo.isSystemApp();
11012             return res;
11013         }
11014
11015         @Override
11016         protected void sortResults(List<ResolveInfo> results) {
11017             Collections.sort(results, mResolvePrioritySorter);
11018         }
11019
11020         @Override
11021         protected void dumpFilter(PrintWriter out, String prefix,
11022                 PackageParser.ActivityIntentInfo filter) {
11023             out.print(prefix); out.print(
11024                     Integer.toHexString(System.identityHashCode(filter.activity)));
11025                     out.print(' ');
11026                     filter.activity.printComponentShortName(out);
11027                     out.print(" filter ");
11028                     out.println(Integer.toHexString(System.identityHashCode(filter)));
11029         }
11030
11031         @Override
11032         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
11033             return filter.activity;
11034         }
11035
11036         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11037             PackageParser.Activity activity = (PackageParser.Activity)label;
11038             out.print(prefix); out.print(
11039                     Integer.toHexString(System.identityHashCode(activity)));
11040                     out.print(' ');
11041                     activity.printComponentShortName(out);
11042             if (count > 1) {
11043                 out.print(" ("); out.print(count); out.print(" filters)");
11044             }
11045             out.println();
11046         }
11047
11048         // Keys are String (activity class name), values are Activity.
11049         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
11050                 = new ArrayMap<ComponentName, PackageParser.Activity>();
11051         private int mFlags;
11052     }
11053
11054     private final class ServiceIntentResolver
11055             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
11056         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11057                 boolean defaultOnly, int userId) {
11058             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
11059             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11060         }
11061
11062         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11063                 int userId) {
11064             if (!sUserManager.exists(userId)) return null;
11065             mFlags = flags;
11066             return super.queryIntent(intent, resolvedType,
11067                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
11068         }
11069
11070         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11071                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
11072             if (!sUserManager.exists(userId)) return null;
11073             if (packageServices == null) {
11074                 return null;
11075             }
11076             mFlags = flags;
11077             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
11078             final int N = packageServices.size();
11079             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
11080                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
11081
11082             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
11083             for (int i = 0; i < N; ++i) {
11084                 intentFilters = packageServices.get(i).intents;
11085                 if (intentFilters != null && intentFilters.size() > 0) {
11086                     PackageParser.ServiceIntentInfo[] array =
11087                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
11088                     intentFilters.toArray(array);
11089                     listCut.add(array);
11090                 }
11091             }
11092             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11093         }
11094
11095         public final void addService(PackageParser.Service s) {
11096             mServices.put(s.getComponentName(), s);
11097             if (DEBUG_SHOW_INFO) {
11098                 Log.v(TAG, "  "
11099                         + (s.info.nonLocalizedLabel != null
11100                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
11101                 Log.v(TAG, "    Class=" + s.info.name);
11102             }
11103             final int NI = s.intents.size();
11104             int j;
11105             for (j=0; j<NI; j++) {
11106                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
11107                 if (DEBUG_SHOW_INFO) {
11108                     Log.v(TAG, "    IntentFilter:");
11109                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11110                 }
11111                 if (!intent.debugCheck()) {
11112                     Log.w(TAG, "==> For Service " + s.info.name);
11113                 }
11114                 addFilter(intent);
11115             }
11116         }
11117
11118         public final void removeService(PackageParser.Service s) {
11119             mServices.remove(s.getComponentName());
11120             if (DEBUG_SHOW_INFO) {
11121                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
11122                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
11123                 Log.v(TAG, "    Class=" + s.info.name);
11124             }
11125             final int NI = s.intents.size();
11126             int j;
11127             for (j=0; j<NI; j++) {
11128                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
11129                 if (DEBUG_SHOW_INFO) {
11130                     Log.v(TAG, "    IntentFilter:");
11131                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11132                 }
11133                 removeFilter(intent);
11134             }
11135         }
11136
11137         @Override
11138         protected boolean allowFilterResult(
11139                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
11140             ServiceInfo filterSi = filter.service.info;
11141             for (int i=dest.size()-1; i>=0; i--) {
11142                 ServiceInfo destAi = dest.get(i).serviceInfo;
11143                 if (destAi.name == filterSi.name
11144                         && destAi.packageName == filterSi.packageName) {
11145                     return false;
11146                 }
11147             }
11148             return true;
11149         }
11150
11151         @Override
11152         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
11153             return new PackageParser.ServiceIntentInfo[size];
11154         }
11155
11156         @Override
11157         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
11158             if (!sUserManager.exists(userId)) return true;
11159             PackageParser.Package p = filter.service.owner;
11160             if (p != null) {
11161                 PackageSetting ps = (PackageSetting)p.mExtras;
11162                 if (ps != null) {
11163                     // System apps are never considered stopped for purposes of
11164                     // filtering, because there may be no way for the user to
11165                     // actually re-launch them.
11166                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
11167                             && ps.getStopped(userId);
11168                 }
11169             }
11170             return false;
11171         }
11172
11173         @Override
11174         protected boolean isPackageForFilter(String packageName,
11175                 PackageParser.ServiceIntentInfo info) {
11176             return packageName.equals(info.service.owner.packageName);
11177         }
11178
11179         @Override
11180         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
11181                 int match, int userId) {
11182             if (!sUserManager.exists(userId)) return null;
11183             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
11184             if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
11185                 return null;
11186             }
11187             final PackageParser.Service service = info.service;
11188             PackageSetting ps = (PackageSetting) service.owner.mExtras;
11189             if (ps == null) {
11190                 return null;
11191             }
11192             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
11193                     ps.readUserState(userId), userId);
11194             if (si == null) {
11195                 return null;
11196             }
11197             final ResolveInfo res = new ResolveInfo();
11198             res.serviceInfo = si;
11199             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
11200                 res.filter = filter;
11201             }
11202             res.priority = info.getPriority();
11203             res.preferredOrder = service.owner.mPreferredOrder;
11204             res.match = match;
11205             res.isDefault = info.hasDefault;
11206             res.labelRes = info.labelRes;
11207             res.nonLocalizedLabel = info.nonLocalizedLabel;
11208             res.icon = info.icon;
11209             res.system = res.serviceInfo.applicationInfo.isSystemApp();
11210             return res;
11211         }
11212
11213         @Override
11214         protected void sortResults(List<ResolveInfo> results) {
11215             Collections.sort(results, mResolvePrioritySorter);
11216         }
11217
11218         @Override
11219         protected void dumpFilter(PrintWriter out, String prefix,
11220                 PackageParser.ServiceIntentInfo filter) {
11221             out.print(prefix); out.print(
11222                     Integer.toHexString(System.identityHashCode(filter.service)));
11223                     out.print(' ');
11224                     filter.service.printComponentShortName(out);
11225                     out.print(" filter ");
11226                     out.println(Integer.toHexString(System.identityHashCode(filter)));
11227         }
11228
11229         @Override
11230         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
11231             return filter.service;
11232         }
11233
11234         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11235             PackageParser.Service service = (PackageParser.Service)label;
11236             out.print(prefix); out.print(
11237                     Integer.toHexString(System.identityHashCode(service)));
11238                     out.print(' ');
11239                     service.printComponentShortName(out);
11240             if (count > 1) {
11241                 out.print(" ("); out.print(count); out.print(" filters)");
11242             }
11243             out.println();
11244         }
11245
11246 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
11247 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
11248 //            final List<ResolveInfo> retList = Lists.newArrayList();
11249 //            while (i.hasNext()) {
11250 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
11251 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
11252 //                    retList.add(resolveInfo);
11253 //                }
11254 //            }
11255 //            return retList;
11256 //        }
11257
11258         // Keys are String (activity class name), values are Activity.
11259         private final ArrayMap<ComponentName, PackageParser.Service> mServices
11260                 = new ArrayMap<ComponentName, PackageParser.Service>();
11261         private int mFlags;
11262     };
11263
11264     private final class ProviderIntentResolver
11265             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
11266         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11267                 boolean defaultOnly, int userId) {
11268             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
11269             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11270         }
11271
11272         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11273                 int userId) {
11274             if (!sUserManager.exists(userId))
11275                 return null;
11276             mFlags = flags;
11277             return super.queryIntent(intent, resolvedType,
11278                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
11279         }
11280
11281         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11282                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
11283             if (!sUserManager.exists(userId))
11284                 return null;
11285             if (packageProviders == null) {
11286                 return null;
11287             }
11288             mFlags = flags;
11289             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11290             final int N = packageProviders.size();
11291             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
11292                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
11293
11294             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
11295             for (int i = 0; i < N; ++i) {
11296                 intentFilters = packageProviders.get(i).intents;
11297                 if (intentFilters != null && intentFilters.size() > 0) {
11298                     PackageParser.ProviderIntentInfo[] array =
11299                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
11300                     intentFilters.toArray(array);
11301                     listCut.add(array);
11302                 }
11303             }
11304             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11305         }
11306
11307         public final void addProvider(PackageParser.Provider p) {
11308             if (mProviders.containsKey(p.getComponentName())) {
11309                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
11310                 return;
11311             }
11312
11313             mProviders.put(p.getComponentName(), p);
11314             if (DEBUG_SHOW_INFO) {
11315                 Log.v(TAG, "  "
11316                         + (p.info.nonLocalizedLabel != null
11317                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
11318                 Log.v(TAG, "    Class=" + p.info.name);
11319             }
11320             final int NI = p.intents.size();
11321             int j;
11322             for (j = 0; j < NI; j++) {
11323                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11324                 if (DEBUG_SHOW_INFO) {
11325                     Log.v(TAG, "    IntentFilter:");
11326                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11327                 }
11328                 if (!intent.debugCheck()) {
11329                     Log.w(TAG, "==> For Provider " + p.info.name);
11330                 }
11331                 addFilter(intent);
11332             }
11333         }
11334
11335         public final void removeProvider(PackageParser.Provider p) {
11336             mProviders.remove(p.getComponentName());
11337             if (DEBUG_SHOW_INFO) {
11338                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
11339                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
11340                 Log.v(TAG, "    Class=" + p.info.name);
11341             }
11342             final int NI = p.intents.size();
11343             int j;
11344             for (j = 0; j < NI; j++) {
11345                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11346                 if (DEBUG_SHOW_INFO) {
11347                     Log.v(TAG, "    IntentFilter:");
11348                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11349                 }
11350                 removeFilter(intent);
11351             }
11352         }
11353
11354         @Override
11355         protected boolean allowFilterResult(
11356                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
11357             ProviderInfo filterPi = filter.provider.info;
11358             for (int i = dest.size() - 1; i >= 0; i--) {
11359                 ProviderInfo destPi = dest.get(i).providerInfo;
11360                 if (destPi.name == filterPi.name
11361                         && destPi.packageName == filterPi.packageName) {
11362                     return false;
11363                 }
11364             }
11365             return true;
11366         }
11367
11368         @Override
11369         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
11370             return new PackageParser.ProviderIntentInfo[size];
11371         }
11372
11373         @Override
11374         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
11375             if (!sUserManager.exists(userId))
11376                 return true;
11377             PackageParser.Package p = filter.provider.owner;
11378             if (p != null) {
11379                 PackageSetting ps = (PackageSetting) p.mExtras;
11380                 if (ps != null) {
11381                     // System apps are never considered stopped for purposes of
11382                     // filtering, because there may be no way for the user to
11383                     // actually re-launch them.
11384                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
11385                             && ps.getStopped(userId);
11386                 }
11387             }
11388             return false;
11389         }
11390
11391         @Override
11392         protected boolean isPackageForFilter(String packageName,
11393                 PackageParser.ProviderIntentInfo info) {
11394             return packageName.equals(info.provider.owner.packageName);
11395         }
11396
11397         @Override
11398         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
11399                 int match, int userId) {
11400             if (!sUserManager.exists(userId))
11401                 return null;
11402             final PackageParser.ProviderIntentInfo info = filter;
11403             if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
11404                 return null;
11405             }
11406             final PackageParser.Provider provider = info.provider;
11407             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
11408             if (ps == null) {
11409                 return null;
11410             }
11411             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
11412                     ps.readUserState(userId), userId);
11413             if (pi == null) {
11414                 return null;
11415             }
11416             final ResolveInfo res = new ResolveInfo();
11417             res.providerInfo = pi;
11418             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
11419                 res.filter = filter;
11420             }
11421             res.priority = info.getPriority();
11422             res.preferredOrder = provider.owner.mPreferredOrder;
11423             res.match = match;
11424             res.isDefault = info.hasDefault;
11425             res.labelRes = info.labelRes;
11426             res.nonLocalizedLabel = info.nonLocalizedLabel;
11427             res.icon = info.icon;
11428             res.system = res.providerInfo.applicationInfo.isSystemApp();
11429             return res;
11430         }
11431
11432         @Override
11433         protected void sortResults(List<ResolveInfo> results) {
11434             Collections.sort(results, mResolvePrioritySorter);
11435         }
11436
11437         @Override
11438         protected void dumpFilter(PrintWriter out, String prefix,
11439                 PackageParser.ProviderIntentInfo filter) {
11440             out.print(prefix);
11441             out.print(
11442                     Integer.toHexString(System.identityHashCode(filter.provider)));
11443             out.print(' ');
11444             filter.provider.printComponentShortName(out);
11445             out.print(" filter ");
11446             out.println(Integer.toHexString(System.identityHashCode(filter)));
11447         }
11448
11449         @Override
11450         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
11451             return filter.provider;
11452         }
11453
11454         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11455             PackageParser.Provider provider = (PackageParser.Provider)label;
11456             out.print(prefix); out.print(
11457                     Integer.toHexString(System.identityHashCode(provider)));
11458                     out.print(' ');
11459                     provider.printComponentShortName(out);
11460             if (count > 1) {
11461                 out.print(" ("); out.print(count); out.print(" filters)");
11462             }
11463             out.println();
11464         }
11465
11466         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
11467                 = new ArrayMap<ComponentName, PackageParser.Provider>();
11468         private int mFlags;
11469     }
11470
11471     private static final class EphemeralIntentResolver
11472             extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
11473         /**
11474          * The result that has the highest defined order. Ordering applies on a
11475          * per-package basis. Mapping is from package name to Pair of order and
11476          * EphemeralResolveInfo.
11477          * <p>
11478          * NOTE: This is implemented as a field variable for convenience and efficiency.
11479          * By having a field variable, we're able to track filter ordering as soon as
11480          * a non-zero order is defined. Otherwise, multiple loops across the result set
11481          * would be needed to apply ordering. If the intent resolver becomes re-entrant,
11482          * this needs to be contained entirely within {@link #filterResults()}.
11483          */
11484         final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
11485
11486         @Override
11487         protected EphemeralResolveIntentInfo[] newArray(int size) {
11488             return new EphemeralResolveIntentInfo[size];
11489         }
11490
11491         @Override
11492         protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
11493             return true;
11494         }
11495
11496         @Override
11497         protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
11498                 int userId) {
11499             if (!sUserManager.exists(userId)) {
11500                 return null;
11501             }
11502             final String packageName = info.getEphemeralResolveInfo().getPackageName();
11503             final Integer order = info.getOrder();
11504             final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
11505                     mOrderResult.get(packageName);
11506             // ordering is enabled and this item's order isn't high enough
11507             if (lastOrderResult != null && lastOrderResult.first >= order) {
11508                 return null;
11509             }
11510             final EphemeralResolveInfo res = info.getEphemeralResolveInfo();
11511             if (order > 0) {
11512                 // non-zero order, enable ordering
11513                 mOrderResult.put(packageName, new Pair<>(order, res));
11514             }
11515             return res;
11516         }
11517
11518         @Override
11519         protected void filterResults(List<EphemeralResolveInfo> results) {
11520             // only do work if ordering is enabled [most of the time it won't be]
11521             if (mOrderResult.size() == 0) {
11522                 return;
11523             }
11524             int resultSize = results.size();
11525             for (int i = 0; i < resultSize; i++) {
11526                 final EphemeralResolveInfo info = results.get(i);
11527                 final String packageName = info.getPackageName();
11528                 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
11529                 if (savedInfo == null) {
11530                     // package doesn't having ordering
11531                     continue;
11532                 }
11533                 if (savedInfo.second == info) {
11534                     // circled back to the highest ordered item; remove from order list
11535                     mOrderResult.remove(savedInfo);
11536                     if (mOrderResult.size() == 0) {
11537                         // no more ordered items
11538                         break;
11539                     }
11540                     continue;
11541                 }
11542                 // item has a worse order, remove it from the result list
11543                 results.remove(i);
11544                 resultSize--;
11545                 i--;
11546             }
11547         }
11548     }
11549
11550     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
11551             new Comparator<ResolveInfo>() {
11552         public int compare(ResolveInfo r1, ResolveInfo r2) {
11553             int v1 = r1.priority;
11554             int v2 = r2.priority;
11555             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
11556             if (v1 != v2) {
11557                 return (v1 > v2) ? -1 : 1;
11558             }
11559             v1 = r1.preferredOrder;
11560             v2 = r2.preferredOrder;
11561             if (v1 != v2) {
11562                 return (v1 > v2) ? -1 : 1;
11563             }
11564             if (r1.isDefault != r2.isDefault) {
11565                 return r1.isDefault ? -1 : 1;
11566             }
11567             v1 = r1.match;
11568             v2 = r2.match;
11569             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
11570             if (v1 != v2) {
11571                 return (v1 > v2) ? -1 : 1;
11572             }
11573             if (r1.system != r2.system) {
11574                 return r1.system ? -1 : 1;
11575             }
11576             if (r1.activityInfo != null) {
11577                 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
11578             }
11579             if (r1.serviceInfo != null) {
11580                 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
11581             }
11582             if (r1.providerInfo != null) {
11583                 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
11584             }
11585             return 0;
11586         }
11587     };
11588
11589     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
11590             new Comparator<ProviderInfo>() {
11591         public int compare(ProviderInfo p1, ProviderInfo p2) {
11592             final int v1 = p1.initOrder;
11593             final int v2 = p2.initOrder;
11594             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
11595         }
11596     };
11597
11598     final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
11599             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
11600             final int[] userIds) {
11601         mHandler.post(new Runnable() {
11602             @Override
11603             public void run() {
11604                 try {
11605                     final IActivityManager am = ActivityManagerNative.getDefault();
11606                     if (am == null) return;
11607                     final int[] resolvedUserIds;
11608                     if (userIds == null) {
11609                         resolvedUserIds = am.getRunningUserIds();
11610                     } else {
11611                         resolvedUserIds = userIds;
11612                     }
11613                     for (int id : resolvedUserIds) {
11614                         final Intent intent = new Intent(action,
11615                                 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
11616                         if (extras != null) {
11617                             intent.putExtras(extras);
11618                         }
11619                         if (targetPkg != null) {
11620                             intent.setPackage(targetPkg);
11621                         }
11622                         // Modify the UID when posting to other users
11623                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
11624                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
11625                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
11626                             intent.putExtra(Intent.EXTRA_UID, uid);
11627                         }
11628                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
11629                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
11630                         if (DEBUG_BROADCASTS) {
11631                             RuntimeException here = new RuntimeException("here");
11632                             here.fillInStackTrace();
11633                             Slog.d(TAG, "Sending to user " + id + ": "
11634                                     + intent.toShortString(false, true, false, false)
11635                                     + " " + intent.getExtras(), here);
11636                         }
11637                         am.broadcastIntent(null, intent, null, finishedReceiver,
11638                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
11639                                 null, finishedReceiver != null, false, id);
11640                     }
11641                 } catch (RemoteException ex) {
11642                 }
11643             }
11644         });
11645     }
11646
11647     /**
11648      * Check if the external storage media is available. This is true if there
11649      * is a mounted external storage medium or if the external storage is
11650      * emulated.
11651      */
11652     private boolean isExternalMediaAvailable() {
11653         return mMediaMounted || Environment.isExternalStorageEmulated();
11654     }
11655
11656     @Override
11657     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
11658         // writer
11659         synchronized (mPackages) {
11660             if (!isExternalMediaAvailable()) {
11661                 // If the external storage is no longer mounted at this point,
11662                 // the caller may not have been able to delete all of this
11663                 // packages files and can not delete any more.  Bail.
11664                 return null;
11665             }
11666             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
11667             if (lastPackage != null) {
11668                 pkgs.remove(lastPackage);
11669             }
11670             if (pkgs.size() > 0) {
11671                 return pkgs.get(0);
11672             }
11673         }
11674         return null;
11675     }
11676
11677     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
11678         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
11679                 userId, andCode ? 1 : 0, packageName);
11680         if (mSystemReady) {
11681             msg.sendToTarget();
11682         } else {
11683             if (mPostSystemReadyMessages == null) {
11684                 mPostSystemReadyMessages = new ArrayList<>();
11685             }
11686             mPostSystemReadyMessages.add(msg);
11687         }
11688     }
11689
11690     void startCleaningPackages() {
11691         // reader
11692         if (!isExternalMediaAvailable()) {
11693             return;
11694         }
11695         synchronized (mPackages) {
11696             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
11697                 return;
11698             }
11699         }
11700         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
11701         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
11702         IActivityManager am = ActivityManagerNative.getDefault();
11703         if (am != null) {
11704             try {
11705                 am.startService(null, intent, null, mContext.getOpPackageName(),
11706                         UserHandle.USER_SYSTEM);
11707             } catch (RemoteException e) {
11708             }
11709         }
11710     }
11711
11712     @Override
11713     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
11714             int installFlags, String installerPackageName, int userId) {
11715         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
11716
11717         final int callingUid = Binder.getCallingUid();
11718         enforceCrossUserPermission(callingUid, userId,
11719                 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
11720
11721         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11722             try {
11723                 if (observer != null) {
11724                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
11725                 }
11726             } catch (RemoteException re) {
11727             }
11728             return;
11729         }
11730
11731         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
11732             installFlags |= PackageManager.INSTALL_FROM_ADB;
11733
11734         } else {
11735             // Caller holds INSTALL_PACKAGES permission, so we're less strict
11736             // about installerPackageName.
11737
11738             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
11739             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
11740         }
11741
11742         UserHandle user;
11743         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
11744             user = UserHandle.ALL;
11745         } else {
11746             user = new UserHandle(userId);
11747         }
11748
11749         // Only system components can circumvent runtime permissions when installing.
11750         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
11751                 && mContext.checkCallingOrSelfPermission(Manifest.permission
11752                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
11753             throw new SecurityException("You need the "
11754                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
11755                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
11756         }
11757
11758         final File originFile = new File(originPath);
11759         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
11760
11761         final Message msg = mHandler.obtainMessage(INIT_COPY);
11762         final VerificationInfo verificationInfo = new VerificationInfo(
11763                 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
11764         final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
11765                 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
11766                 null /*packageAbiOverride*/, null /*grantedPermissions*/,
11767                 null /*certificates*/);
11768         params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
11769         msg.obj = params;
11770
11771         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
11772                 System.identityHashCode(msg.obj));
11773         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11774                 System.identityHashCode(msg.obj));
11775
11776         mHandler.sendMessage(msg);
11777     }
11778
11779     void installStage(String packageName, File stagedDir, String stagedCid,
11780             IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
11781             String installerPackageName, int installerUid, UserHandle user,
11782             Certificate[][] certificates) {
11783         if (DEBUG_EPHEMERAL) {
11784             if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
11785                 Slog.d(TAG, "Ephemeral install of " + packageName);
11786             }
11787         }
11788         final VerificationInfo verificationInfo = new VerificationInfo(
11789                 sessionParams.originatingUri, sessionParams.referrerUri,
11790                 sessionParams.originatingUid, installerUid);
11791
11792         final OriginInfo origin;
11793         if (stagedDir != null) {
11794             origin = OriginInfo.fromStagedFile(stagedDir);
11795         } else {
11796             origin = OriginInfo.fromStagedContainer(stagedCid);
11797         }
11798
11799         final Message msg = mHandler.obtainMessage(INIT_COPY);
11800         final InstallParams params = new InstallParams(origin, null, observer,
11801                 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
11802                 verificationInfo, user, sessionParams.abiOverride,
11803                 sessionParams.grantedRuntimePermissions, certificates);
11804         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
11805         msg.obj = params;
11806
11807         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
11808                 System.identityHashCode(msg.obj));
11809         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11810                 System.identityHashCode(msg.obj));
11811
11812         mHandler.sendMessage(msg);
11813     }
11814
11815     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
11816             int userId) {
11817         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
11818         sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
11819     }
11820
11821     private void sendPackageAddedForUser(String packageName, boolean isSystem,
11822             int appId, int userId) {
11823         Bundle extras = new Bundle(1);
11824         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
11825
11826         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
11827                 packageName, extras, 0, null, null, new int[] {userId});
11828         try {
11829             IActivityManager am = ActivityManagerNative.getDefault();
11830             if (isSystem && am.isUserRunning(userId, 0)) {
11831                 // The just-installed/enabled app is bundled on the system, so presumed
11832                 // to be able to run automatically without needing an explicit launch.
11833                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
11834                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
11835                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
11836                         .setPackage(packageName);
11837                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
11838                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
11839             }
11840         } catch (RemoteException e) {
11841             // shouldn't happen
11842             Slog.w(TAG, "Unable to bootstrap installed package", e);
11843         }
11844     }
11845
11846     @Override
11847     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
11848             int userId) {
11849         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11850         PackageSetting pkgSetting;
11851         final int uid = Binder.getCallingUid();
11852         enforceCrossUserPermission(uid, userId,
11853                 true /* requireFullPermission */, true /* checkShell */,
11854                 "setApplicationHiddenSetting for user " + userId);
11855
11856         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
11857             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
11858             return false;
11859         }
11860
11861         long callingId = Binder.clearCallingIdentity();
11862         try {
11863             boolean sendAdded = false;
11864             boolean sendRemoved = false;
11865             // writer
11866             synchronized (mPackages) {
11867                 pkgSetting = mSettings.mPackages.get(packageName);
11868                 if (pkgSetting == null) {
11869                     return false;
11870                 }
11871                 // Do not allow "android" is being disabled
11872                 if ("android".equals(packageName)) {
11873                     Slog.w(TAG, "Cannot hide package: android");
11874                     return false;
11875                 }
11876                 // Only allow protected packages to hide themselves.
11877                 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
11878                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
11879                     Slog.w(TAG, "Not hiding protected package: " + packageName);
11880                     return false;
11881                 }
11882
11883                 if (pkgSetting.getHidden(userId) != hidden) {
11884                     pkgSetting.setHidden(hidden, userId);
11885                     mSettings.writePackageRestrictionsLPr(userId);
11886                     if (hidden) {
11887                         sendRemoved = true;
11888                     } else {
11889                         sendAdded = true;
11890                     }
11891                 }
11892             }
11893             if (sendAdded) {
11894                 sendPackageAddedForUser(packageName, pkgSetting, userId);
11895                 return true;
11896             }
11897             if (sendRemoved) {
11898                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
11899                         "hiding pkg");
11900                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
11901                 return true;
11902             }
11903         } finally {
11904             Binder.restoreCallingIdentity(callingId);
11905         }
11906         return false;
11907     }
11908
11909     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
11910             int userId) {
11911         final PackageRemovedInfo info = new PackageRemovedInfo();
11912         info.removedPackage = packageName;
11913         info.removedUsers = new int[] {userId};
11914         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
11915         info.sendPackageRemovedBroadcasts(true /*killApp*/);
11916     }
11917
11918     private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
11919         if (pkgList.length > 0) {
11920             Bundle extras = new Bundle(1);
11921             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
11922
11923             sendPackageBroadcast(
11924                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
11925                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
11926                     null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
11927                     new int[] {userId});
11928         }
11929     }
11930
11931     /**
11932      * Returns true if application is not found or there was an error. Otherwise it returns
11933      * the hidden state of the package for the given user.
11934      */
11935     @Override
11936     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
11937         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11938         enforceCrossUserPermission(Binder.getCallingUid(), userId,
11939                 true /* requireFullPermission */, false /* checkShell */,
11940                 "getApplicationHidden for user " + userId);
11941         PackageSetting pkgSetting;
11942         long callingId = Binder.clearCallingIdentity();
11943         try {
11944             // writer
11945             synchronized (mPackages) {
11946                 pkgSetting = mSettings.mPackages.get(packageName);
11947                 if (pkgSetting == null) {
11948                     return true;
11949                 }
11950                 return pkgSetting.getHidden(userId);
11951             }
11952         } finally {
11953             Binder.restoreCallingIdentity(callingId);
11954         }
11955     }
11956
11957     /**
11958      * @hide
11959      */
11960     @Override
11961     public int installExistingPackageAsUser(String packageName, int userId) {
11962         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
11963                 null);
11964         PackageSetting pkgSetting;
11965         final int uid = Binder.getCallingUid();
11966         enforceCrossUserPermission(uid, userId,
11967                 true /* requireFullPermission */, true /* checkShell */,
11968                 "installExistingPackage for user " + userId);
11969         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11970             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
11971         }
11972
11973         long callingId = Binder.clearCallingIdentity();
11974         try {
11975             boolean installed = false;
11976
11977             // writer
11978             synchronized (mPackages) {
11979                 pkgSetting = mSettings.mPackages.get(packageName);
11980                 if (pkgSetting == null) {
11981                     return PackageManager.INSTALL_FAILED_INVALID_URI;
11982                 }
11983                 if (!pkgSetting.getInstalled(userId)) {
11984                     pkgSetting.setInstalled(true, userId);
11985                     pkgSetting.setHidden(false, userId);
11986                     mSettings.writePackageRestrictionsLPr(userId);
11987                     installed = true;
11988                 }
11989             }
11990
11991             if (installed) {
11992                 if (pkgSetting.pkg != null) {
11993                     synchronized (mInstallLock) {
11994                         // We don't need to freeze for a brand new install
11995                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
11996                     }
11997                 }
11998                 sendPackageAddedForUser(packageName, pkgSetting, userId);
11999             }
12000         } finally {
12001             Binder.restoreCallingIdentity(callingId);
12002         }
12003
12004         return PackageManager.INSTALL_SUCCEEDED;
12005     }
12006
12007     boolean isUserRestricted(int userId, String restrictionKey) {
12008         Bundle restrictions = sUserManager.getUserRestrictions(userId);
12009         if (restrictions.getBoolean(restrictionKey, false)) {
12010             Log.w(TAG, "User is restricted: " + restrictionKey);
12011             return true;
12012         }
12013         return false;
12014     }
12015
12016     @Override
12017     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
12018             int userId) {
12019         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
12020         enforceCrossUserPermission(Binder.getCallingUid(), userId,
12021                 true /* requireFullPermission */, true /* checkShell */,
12022                 "setPackagesSuspended for user " + userId);
12023
12024         if (ArrayUtils.isEmpty(packageNames)) {
12025             return packageNames;
12026         }
12027
12028         // List of package names for whom the suspended state has changed.
12029         List<String> changedPackages = new ArrayList<>(packageNames.length);
12030         // List of package names for whom the suspended state is not set as requested in this
12031         // method.
12032         List<String> unactionedPackages = new ArrayList<>(packageNames.length);
12033         long callingId = Binder.clearCallingIdentity();
12034         try {
12035             for (int i = 0; i < packageNames.length; i++) {
12036                 String packageName = packageNames[i];
12037                 boolean changed = false;
12038                 final int appId;
12039                 synchronized (mPackages) {
12040                     final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12041                     if (pkgSetting == null) {
12042                         Slog.w(TAG, "Could not find package setting for package \"" + packageName
12043                                 + "\". Skipping suspending/un-suspending.");
12044                         unactionedPackages.add(packageName);
12045                         continue;
12046                     }
12047                     appId = pkgSetting.appId;
12048                     if (pkgSetting.getSuspended(userId) != suspended) {
12049                         if (!canSuspendPackageForUserLocked(packageName, userId)) {
12050                             unactionedPackages.add(packageName);
12051                             continue;
12052                         }
12053                         pkgSetting.setSuspended(suspended, userId);
12054                         mSettings.writePackageRestrictionsLPr(userId);
12055                         changed = true;
12056                         changedPackages.add(packageName);
12057                     }
12058                 }
12059
12060                 if (changed && suspended) {
12061                     killApplication(packageName, UserHandle.getUid(userId, appId),
12062                             "suspending package");
12063                 }
12064             }
12065         } finally {
12066             Binder.restoreCallingIdentity(callingId);
12067         }
12068
12069         if (!changedPackages.isEmpty()) {
12070             sendPackagesSuspendedForUser(changedPackages.toArray(
12071                     new String[changedPackages.size()]), userId, suspended);
12072         }
12073
12074         return unactionedPackages.toArray(new String[unactionedPackages.size()]);
12075     }
12076
12077     @Override
12078     public boolean isPackageSuspendedForUser(String packageName, int userId) {
12079         enforceCrossUserPermission(Binder.getCallingUid(), userId,
12080                 true /* requireFullPermission */, false /* checkShell */,
12081                 "isPackageSuspendedForUser for user " + userId);
12082         synchronized (mPackages) {
12083             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12084             if (pkgSetting == null) {
12085                 throw new IllegalArgumentException("Unknown target package: " + packageName);
12086             }
12087             return pkgSetting.getSuspended(userId);
12088         }
12089     }
12090
12091     private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
12092         if (isPackageDeviceAdmin(packageName, userId)) {
12093             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12094                     + "\": has an active device admin");
12095             return false;
12096         }
12097
12098         String activeLauncherPackageName = getActiveLauncherPackageName(userId);
12099         if (packageName.equals(activeLauncherPackageName)) {
12100             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12101                     + "\": contains the active launcher");
12102             return false;
12103         }
12104
12105         if (packageName.equals(mRequiredInstallerPackage)) {
12106             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12107                     + "\": required for package installation");
12108             return false;
12109         }
12110
12111         if (packageName.equals(mRequiredUninstallerPackage)) {
12112             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12113                     + "\": required for package uninstallation");
12114             return false;
12115         }
12116
12117         if (packageName.equals(mRequiredVerifierPackage)) {
12118             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12119                     + "\": required for package verification");
12120             return false;
12121         }
12122
12123         if (packageName.equals(getDefaultDialerPackageName(userId))) {
12124             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12125                     + "\": is the default dialer");
12126             return false;
12127         }
12128
12129         if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
12130             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12131                     + "\": protected package");
12132             return false;
12133         }
12134
12135         return true;
12136     }
12137
12138     private String getActiveLauncherPackageName(int userId) {
12139         Intent intent = new Intent(Intent.ACTION_MAIN);
12140         intent.addCategory(Intent.CATEGORY_HOME);
12141         ResolveInfo resolveInfo = resolveIntent(
12142                 intent,
12143                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
12144                 PackageManager.MATCH_DEFAULT_ONLY,
12145                 userId);
12146
12147         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
12148     }
12149
12150     private String getDefaultDialerPackageName(int userId) {
12151         synchronized (mPackages) {
12152             return mSettings.getDefaultDialerPackageNameLPw(userId);
12153         }
12154     }
12155
12156     @Override
12157     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
12158         mContext.enforceCallingOrSelfPermission(
12159                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12160                 "Only package verification agents can verify applications");
12161
12162         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
12163         final PackageVerificationResponse response = new PackageVerificationResponse(
12164                 verificationCode, Binder.getCallingUid());
12165         msg.arg1 = id;
12166         msg.obj = response;
12167         mHandler.sendMessage(msg);
12168     }
12169
12170     @Override
12171     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
12172             long millisecondsToDelay) {
12173         mContext.enforceCallingOrSelfPermission(
12174                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12175                 "Only package verification agents can extend verification timeouts");
12176
12177         final PackageVerificationState state = mPendingVerification.get(id);
12178         final PackageVerificationResponse response = new PackageVerificationResponse(
12179                 verificationCodeAtTimeout, Binder.getCallingUid());
12180
12181         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
12182             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
12183         }
12184         if (millisecondsToDelay < 0) {
12185             millisecondsToDelay = 0;
12186         }
12187         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
12188                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
12189             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
12190         }
12191
12192         if ((state != null) && !state.timeoutExtended()) {
12193             state.extendTimeout();
12194
12195             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
12196             msg.arg1 = id;
12197             msg.obj = response;
12198             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
12199         }
12200     }
12201
12202     private void broadcastPackageVerified(int verificationId, Uri packageUri,
12203             int verificationCode, UserHandle user) {
12204         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
12205         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
12206         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
12207         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
12208         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
12209
12210         mContext.sendBroadcastAsUser(intent, user,
12211                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
12212     }
12213
12214     private ComponentName matchComponentForVerifier(String packageName,
12215             List<ResolveInfo> receivers) {
12216         ActivityInfo targetReceiver = null;
12217
12218         final int NR = receivers.size();
12219         for (int i = 0; i < NR; i++) {
12220             final ResolveInfo info = receivers.get(i);
12221             if (info.activityInfo == null) {
12222                 continue;
12223             }
12224
12225             if (packageName.equals(info.activityInfo.packageName)) {
12226                 targetReceiver = info.activityInfo;
12227                 break;
12228             }
12229         }
12230
12231         if (targetReceiver == null) {
12232             return null;
12233         }
12234
12235         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
12236     }
12237
12238     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
12239             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
12240         if (pkgInfo.verifiers.length == 0) {
12241             return null;
12242         }
12243
12244         final int N = pkgInfo.verifiers.length;
12245         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
12246         for (int i = 0; i < N; i++) {
12247             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
12248
12249             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
12250                     receivers);
12251             if (comp == null) {
12252                 continue;
12253             }
12254
12255             final int verifierUid = getUidForVerifier(verifierInfo);
12256             if (verifierUid == -1) {
12257                 continue;
12258             }
12259
12260             if (DEBUG_VERIFY) {
12261                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
12262                         + " with the correct signature");
12263             }
12264             sufficientVerifiers.add(comp);
12265             verificationState.addSufficientVerifier(verifierUid);
12266         }
12267
12268         return sufficientVerifiers;
12269     }
12270
12271     private int getUidForVerifier(VerifierInfo verifierInfo) {
12272         synchronized (mPackages) {
12273             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
12274             if (pkg == null) {
12275                 return -1;
12276             } else if (pkg.mSignatures.length != 1) {
12277                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
12278                         + " has more than one signature; ignoring");
12279                 return -1;
12280             }
12281
12282             /*
12283              * If the public key of the package's signature does not match
12284              * our expected public key, then this is a different package and
12285              * we should skip.
12286              */
12287
12288             final byte[] expectedPublicKey;
12289             try {
12290                 final Signature verifierSig = pkg.mSignatures[0];
12291                 final PublicKey publicKey = verifierSig.getPublicKey();
12292                 expectedPublicKey = publicKey.getEncoded();
12293             } catch (CertificateException e) {
12294                 return -1;
12295             }
12296
12297             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
12298
12299             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
12300                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
12301                         + " does not have the expected public key; ignoring");
12302                 return -1;
12303             }
12304
12305             return pkg.applicationInfo.uid;
12306         }
12307     }
12308
12309     @Override
12310     public void finishPackageInstall(int token, boolean didLaunch) {
12311         enforceSystemOrRoot("Only the system is allowed to finish installs");
12312
12313         if (DEBUG_INSTALL) {
12314             Slog.v(TAG, "BM finishing package install for " + token);
12315         }
12316         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
12317
12318         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
12319         mHandler.sendMessage(msg);
12320     }
12321
12322     /**
12323      * Get the verification agent timeout.
12324      *
12325      * @return verification timeout in milliseconds
12326      */
12327     private long getVerificationTimeout() {
12328         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
12329                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
12330                 DEFAULT_VERIFICATION_TIMEOUT);
12331     }
12332
12333     /**
12334      * Get the default verification agent response code.
12335      *
12336      * @return default verification response code
12337      */
12338     private int getDefaultVerificationResponse() {
12339         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12340                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
12341                 DEFAULT_VERIFICATION_RESPONSE);
12342     }
12343
12344     /**
12345      * Check whether or not package verification has been enabled.
12346      *
12347      * @return true if verification should be performed
12348      */
12349     private boolean isVerificationEnabled(int userId, int installFlags) {
12350         if (!DEFAULT_VERIFY_ENABLE) {
12351             return false;
12352         }
12353         // Ephemeral apps don't get the full verification treatment
12354         if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
12355             if (DEBUG_EPHEMERAL) {
12356                 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
12357             }
12358             return false;
12359         }
12360
12361         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
12362
12363         // Check if installing from ADB
12364         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
12365             // Do not run verification in a test harness environment
12366             if (ActivityManager.isRunningInTestHarness()) {
12367                 return false;
12368             }
12369             if (ensureVerifyAppsEnabled) {
12370                 return true;
12371             }
12372             // Check if the developer does not want package verification for ADB installs
12373             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12374                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
12375                 return false;
12376             }
12377         }
12378
12379         if (ensureVerifyAppsEnabled) {
12380             return true;
12381         }
12382
12383         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12384                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
12385     }
12386
12387     @Override
12388     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
12389             throws RemoteException {
12390         mContext.enforceCallingOrSelfPermission(
12391                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
12392                 "Only intentfilter verification agents can verify applications");
12393
12394         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
12395         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
12396                 Binder.getCallingUid(), verificationCode, failedDomains);
12397         msg.arg1 = id;
12398         msg.obj = response;
12399         mHandler.sendMessage(msg);
12400     }
12401
12402     @Override
12403     public int getIntentVerificationStatus(String packageName, int userId) {
12404         synchronized (mPackages) {
12405             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
12406         }
12407     }
12408
12409     @Override
12410     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
12411         mContext.enforceCallingOrSelfPermission(
12412                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12413
12414         boolean result = false;
12415         synchronized (mPackages) {
12416             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
12417         }
12418         if (result) {
12419             scheduleWritePackageRestrictionsLocked(userId);
12420         }
12421         return result;
12422     }
12423
12424     @Override
12425     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
12426             String packageName) {
12427         synchronized (mPackages) {
12428             return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
12429         }
12430     }
12431
12432     @Override
12433     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
12434         if (TextUtils.isEmpty(packageName)) {
12435             return ParceledListSlice.emptyList();
12436         }
12437         synchronized (mPackages) {
12438             PackageParser.Package pkg = mPackages.get(packageName);
12439             if (pkg == null || pkg.activities == null) {
12440                 return ParceledListSlice.emptyList();
12441             }
12442             final int count = pkg.activities.size();
12443             ArrayList<IntentFilter> result = new ArrayList<>();
12444             for (int n=0; n<count; n++) {
12445                 PackageParser.Activity activity = pkg.activities.get(n);
12446                 if (activity.intents != null && activity.intents.size() > 0) {
12447                     result.addAll(activity.intents);
12448                 }
12449             }
12450             return new ParceledListSlice<>(result);
12451         }
12452     }
12453
12454     @Override
12455     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
12456         mContext.enforceCallingOrSelfPermission(
12457                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12458
12459         synchronized (mPackages) {
12460             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
12461             if (packageName != null) {
12462                 result |= updateIntentVerificationStatus(packageName,
12463                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
12464                         userId);
12465                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
12466                         packageName, userId);
12467             }
12468             return result;
12469         }
12470     }
12471
12472     @Override
12473     public String getDefaultBrowserPackageName(int userId) {
12474         synchronized (mPackages) {
12475             return mSettings.getDefaultBrowserPackageNameLPw(userId);
12476         }
12477     }
12478
12479     /**
12480      * Get the "allow unknown sources" setting.
12481      *
12482      * @return the current "allow unknown sources" setting
12483      */
12484     private int getUnknownSourcesSettings() {
12485         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
12486                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
12487                 -1);
12488     }
12489
12490     @Override
12491     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
12492         final int uid = Binder.getCallingUid();
12493         // writer
12494         synchronized (mPackages) {
12495             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
12496             if (targetPackageSetting == null) {
12497                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
12498             }
12499
12500             PackageSetting installerPackageSetting;
12501             if (installerPackageName != null) {
12502                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
12503                 if (installerPackageSetting == null) {
12504                     throw new IllegalArgumentException("Unknown installer package: "
12505                             + installerPackageName);
12506                 }
12507             } else {
12508                 installerPackageSetting = null;
12509             }
12510
12511             Signature[] callerSignature;
12512             Object obj = mSettings.getUserIdLPr(uid);
12513             if (obj != null) {
12514                 if (obj instanceof SharedUserSetting) {
12515                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
12516                 } else if (obj instanceof PackageSetting) {
12517                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
12518                 } else {
12519                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
12520                 }
12521             } else {
12522                 throw new SecurityException("Unknown calling UID: " + uid);
12523             }
12524
12525             // Verify: can't set installerPackageName to a package that is
12526             // not signed with the same cert as the caller.
12527             if (installerPackageSetting != null) {
12528                 if (compareSignatures(callerSignature,
12529                         installerPackageSetting.signatures.mSignatures)
12530                         != PackageManager.SIGNATURE_MATCH) {
12531                     throw new SecurityException(
12532                             "Caller does not have same cert as new installer package "
12533                             + installerPackageName);
12534                 }
12535             }
12536
12537             // Verify: if target already has an installer package, it must
12538             // be signed with the same cert as the caller.
12539             if (targetPackageSetting.installerPackageName != null) {
12540                 PackageSetting setting = mSettings.mPackages.get(
12541                         targetPackageSetting.installerPackageName);
12542                 // If the currently set package isn't valid, then it's always
12543                 // okay to change it.
12544                 if (setting != null) {
12545                     if (compareSignatures(callerSignature,
12546                             setting.signatures.mSignatures)
12547                             != PackageManager.SIGNATURE_MATCH) {
12548                         throw new SecurityException(
12549                                 "Caller does not have same cert as old installer package "
12550                                 + targetPackageSetting.installerPackageName);
12551                     }
12552                 }
12553             }
12554
12555             // Okay!
12556             targetPackageSetting.installerPackageName = installerPackageName;
12557             if (installerPackageName != null) {
12558                 mSettings.mInstallerPackages.add(installerPackageName);
12559             }
12560             scheduleWriteSettingsLocked();
12561         }
12562     }
12563
12564     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
12565         // Queue up an async operation since the package installation may take a little while.
12566         mHandler.post(new Runnable() {
12567             public void run() {
12568                 mHandler.removeCallbacks(this);
12569                  // Result object to be returned
12570                 PackageInstalledInfo res = new PackageInstalledInfo();
12571                 res.setReturnCode(currentStatus);
12572                 res.uid = -1;
12573                 res.pkg = null;
12574                 res.removedInfo = null;
12575                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12576                     args.doPreInstall(res.returnCode);
12577                     synchronized (mInstallLock) {
12578                         installPackageTracedLI(args, res);
12579                     }
12580                     args.doPostInstall(res.returnCode, res.uid);
12581                 }
12582
12583                 // A restore should be performed at this point if (a) the install
12584                 // succeeded, (b) the operation is not an update, and (c) the new
12585                 // package has not opted out of backup participation.
12586                 final boolean update = res.removedInfo != null
12587                         && res.removedInfo.removedPackage != null;
12588                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
12589                 boolean doRestore = !update
12590                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
12591
12592                 // Set up the post-install work request bookkeeping.  This will be used
12593                 // and cleaned up by the post-install event handling regardless of whether
12594                 // there's a restore pass performed.  Token values are >= 1.
12595                 int token;
12596                 if (mNextInstallToken < 0) mNextInstallToken = 1;
12597                 token = mNextInstallToken++;
12598
12599                 PostInstallData data = new PostInstallData(args, res);
12600                 mRunningInstalls.put(token, data);
12601                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
12602
12603                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
12604                     // Pass responsibility to the Backup Manager.  It will perform a
12605                     // restore if appropriate, then pass responsibility back to the
12606                     // Package Manager to run the post-install observer callbacks
12607                     // and broadcasts.
12608                     IBackupManager bm = IBackupManager.Stub.asInterface(
12609                             ServiceManager.getService(Context.BACKUP_SERVICE));
12610                     if (bm != null) {
12611                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
12612                                 + " to BM for possible restore");
12613                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
12614                         try {
12615                             // TODO: http://b/22388012
12616                             if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
12617                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
12618                             } else {
12619                                 doRestore = false;
12620                             }
12621                         } catch (RemoteException e) {
12622                             // can't happen; the backup manager is local
12623                         } catch (Exception e) {
12624                             Slog.e(TAG, "Exception trying to enqueue restore", e);
12625                             doRestore = false;
12626                         }
12627                     } else {
12628                         Slog.e(TAG, "Backup Manager not found!");
12629                         doRestore = false;
12630                     }
12631                 }
12632
12633                 if (!doRestore) {
12634                     // No restore possible, or the Backup Manager was mysteriously not
12635                     // available -- just fire the post-install work request directly.
12636                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
12637
12638                     Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
12639
12640                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
12641                     mHandler.sendMessage(msg);
12642                 }
12643             }
12644         });
12645     }
12646
12647     /**
12648      * Callback from PackageSettings whenever an app is first transitioned out of the
12649      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
12650      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
12651      * here whether the app is the target of an ongoing install, and only send the
12652      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
12653      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
12654      * handling.
12655      */
12656     void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
12657         // Serialize this with the rest of the install-process message chain.  In the
12658         // restore-at-install case, this Runnable will necessarily run before the
12659         // POST_INSTALL message is processed, so the contents of mRunningInstalls
12660         // are coherent.  In the non-restore case, the app has already completed install
12661         // and been launched through some other means, so it is not in a problematic
12662         // state for observers to see the FIRST_LAUNCH signal.
12663         mHandler.post(new Runnable() {
12664             @Override
12665             public void run() {
12666                 for (int i = 0; i < mRunningInstalls.size(); i++) {
12667                     final PostInstallData data = mRunningInstalls.valueAt(i);
12668                     if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12669                         continue;
12670                     }
12671                     if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
12672                         // right package; but is it for the right user?
12673                         for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
12674                             if (userId == data.res.newUsers[uIndex]) {
12675                                 if (DEBUG_BACKUP) {
12676                                     Slog.i(TAG, "Package " + pkgName
12677                                             + " being restored so deferring FIRST_LAUNCH");
12678                                 }
12679                                 return;
12680                             }
12681                         }
12682                     }
12683                 }
12684                 // didn't find it, so not being restored
12685                 if (DEBUG_BACKUP) {
12686                     Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
12687                 }
12688                 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
12689             }
12690         });
12691     }
12692
12693     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
12694         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
12695                 installerPkg, null, userIds);
12696     }
12697
12698     private abstract class HandlerParams {
12699         private static final int MAX_RETRIES = 4;
12700
12701         /**
12702          * Number of times startCopy() has been attempted and had a non-fatal
12703          * error.
12704          */
12705         private int mRetries = 0;
12706
12707         /** User handle for the user requesting the information or installation. */
12708         private final UserHandle mUser;
12709         String traceMethod;
12710         int traceCookie;
12711
12712         HandlerParams(UserHandle user) {
12713             mUser = user;
12714         }
12715
12716         UserHandle getUser() {
12717             return mUser;
12718         }
12719
12720         HandlerParams setTraceMethod(String traceMethod) {
12721             this.traceMethod = traceMethod;
12722             return this;
12723         }
12724
12725         HandlerParams setTraceCookie(int traceCookie) {
12726             this.traceCookie = traceCookie;
12727             return this;
12728         }
12729
12730         final boolean startCopy() {
12731             boolean res;
12732             try {
12733                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
12734
12735                 if (++mRetries > MAX_RETRIES) {
12736                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
12737                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
12738                     handleServiceError();
12739                     return false;
12740                 } else {
12741                     handleStartCopy();
12742                     res = true;
12743                 }
12744             } catch (RemoteException e) {
12745                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
12746                 mHandler.sendEmptyMessage(MCS_RECONNECT);
12747                 res = false;
12748             }
12749             handleReturnCode();
12750             return res;
12751         }
12752
12753         final void serviceError() {
12754             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
12755             handleServiceError();
12756             handleReturnCode();
12757         }
12758
12759         abstract void handleStartCopy() throws RemoteException;
12760         abstract void handleServiceError();
12761         abstract void handleReturnCode();
12762     }
12763
12764     class MeasureParams extends HandlerParams {
12765         private final PackageStats mStats;
12766         private boolean mSuccess;
12767
12768         private final IPackageStatsObserver mObserver;
12769
12770         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
12771             super(new UserHandle(stats.userHandle));
12772             mObserver = observer;
12773             mStats = stats;
12774         }
12775
12776         @Override
12777         public String toString() {
12778             return "MeasureParams{"
12779                 + Integer.toHexString(System.identityHashCode(this))
12780                 + " " + mStats.packageName + "}";
12781         }
12782
12783         @Override
12784         void handleStartCopy() throws RemoteException {
12785             synchronized (mInstallLock) {
12786                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
12787             }
12788
12789             if (mSuccess) {
12790                 boolean mounted = false;
12791                 try {
12792                     final String status = Environment.getExternalStorageState();
12793                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
12794                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
12795                 } catch (Exception e) {
12796                 }
12797
12798                 if (mounted) {
12799                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
12800
12801                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
12802                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
12803
12804                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
12805                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
12806
12807                     // Always subtract cache size, since it's a subdirectory
12808                     mStats.externalDataSize -= mStats.externalCacheSize;
12809
12810                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
12811                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
12812
12813                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
12814                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
12815                 }
12816             }
12817         }
12818
12819         @Override
12820         void handleReturnCode() {
12821             if (mObserver != null) {
12822                 try {
12823                     mObserver.onGetStatsCompleted(mStats, mSuccess);
12824                 } catch (RemoteException e) {
12825                     Slog.i(TAG, "Observer no longer exists.");
12826                 }
12827             }
12828         }
12829
12830         @Override
12831         void handleServiceError() {
12832             Slog.e(TAG, "Could not measure application " + mStats.packageName
12833                             + " external storage");
12834         }
12835     }
12836
12837     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
12838             throws RemoteException {
12839         long result = 0;
12840         for (File path : paths) {
12841             result += mcs.calculateDirectorySize(path.getAbsolutePath());
12842         }
12843         return result;
12844     }
12845
12846     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
12847         for (File path : paths) {
12848             try {
12849                 mcs.clearDirectory(path.getAbsolutePath());
12850             } catch (RemoteException e) {
12851             }
12852         }
12853     }
12854
12855     static class OriginInfo {
12856         /**
12857          * Location where install is coming from, before it has been
12858          * copied/renamed into place. This could be a single monolithic APK
12859          * file, or a cluster directory. This location may be untrusted.
12860          */
12861         final File file;
12862         final String cid;
12863
12864         /**
12865          * Flag indicating that {@link #file} or {@link #cid} has already been
12866          * staged, meaning downstream users don't need to defensively copy the
12867          * contents.
12868          */
12869         final boolean staged;
12870
12871         /**
12872          * Flag indicating that {@link #file} or {@link #cid} is an already
12873          * installed app that is being moved.
12874          */
12875         final boolean existing;
12876
12877         final String resolvedPath;
12878         final File resolvedFile;
12879
12880         static OriginInfo fromNothing() {
12881             return new OriginInfo(null, null, false, false);
12882         }
12883
12884         static OriginInfo fromUntrustedFile(File file) {
12885             return new OriginInfo(file, null, false, false);
12886         }
12887
12888         static OriginInfo fromExistingFile(File file) {
12889             return new OriginInfo(file, null, false, true);
12890         }
12891
12892         static OriginInfo fromStagedFile(File file) {
12893             return new OriginInfo(file, null, true, false);
12894         }
12895
12896         static OriginInfo fromStagedContainer(String cid) {
12897             return new OriginInfo(null, cid, true, false);
12898         }
12899
12900         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
12901             this.file = file;
12902             this.cid = cid;
12903             this.staged = staged;
12904             this.existing = existing;
12905
12906             if (cid != null) {
12907                 resolvedPath = PackageHelper.getSdDir(cid);
12908                 resolvedFile = new File(resolvedPath);
12909             } else if (file != null) {
12910                 resolvedPath = file.getAbsolutePath();
12911                 resolvedFile = file;
12912             } else {
12913                 resolvedPath = null;
12914                 resolvedFile = null;
12915             }
12916         }
12917     }
12918
12919     static class MoveInfo {
12920         final int moveId;
12921         final String fromUuid;
12922         final String toUuid;
12923         final String packageName;
12924         final String dataAppName;
12925         final int appId;
12926         final String seinfo;
12927         final int targetSdkVersion;
12928
12929         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
12930                 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
12931             this.moveId = moveId;
12932             this.fromUuid = fromUuid;
12933             this.toUuid = toUuid;
12934             this.packageName = packageName;
12935             this.dataAppName = dataAppName;
12936             this.appId = appId;
12937             this.seinfo = seinfo;
12938             this.targetSdkVersion = targetSdkVersion;
12939         }
12940     }
12941
12942     static class VerificationInfo {
12943         /** A constant used to indicate that a uid value is not present. */
12944         public static final int NO_UID = -1;
12945
12946         /** URI referencing where the package was downloaded from. */
12947         final Uri originatingUri;
12948
12949         /** HTTP referrer URI associated with the originatingURI. */
12950         final Uri referrer;
12951
12952         /** UID of the application that the install request originated from. */
12953         final int originatingUid;
12954
12955         /** UID of application requesting the install */
12956         final int installerUid;
12957
12958         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
12959             this.originatingUri = originatingUri;
12960             this.referrer = referrer;
12961             this.originatingUid = originatingUid;
12962             this.installerUid = installerUid;
12963         }
12964     }
12965
12966     class InstallParams extends HandlerParams {
12967         final OriginInfo origin;
12968         final MoveInfo move;
12969         final IPackageInstallObserver2 observer;
12970         int installFlags;
12971         final String installerPackageName;
12972         final String volumeUuid;
12973         private InstallArgs mArgs;
12974         private int mRet;
12975         final String packageAbiOverride;
12976         final String[] grantedRuntimePermissions;
12977         final VerificationInfo verificationInfo;
12978         final Certificate[][] certificates;
12979
12980         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
12981                 int installFlags, String installerPackageName, String volumeUuid,
12982                 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
12983                 String[] grantedPermissions, Certificate[][] certificates) {
12984             super(user);
12985             this.origin = origin;
12986             this.move = move;
12987             this.observer = observer;
12988             this.installFlags = installFlags;
12989             this.installerPackageName = installerPackageName;
12990             this.volumeUuid = volumeUuid;
12991             this.verificationInfo = verificationInfo;
12992             this.packageAbiOverride = packageAbiOverride;
12993             this.grantedRuntimePermissions = grantedPermissions;
12994             this.certificates = certificates;
12995         }
12996
12997         @Override
12998         public String toString() {
12999             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
13000                     + " file=" + origin.file + " cid=" + origin.cid + "}";
13001         }
13002
13003         private int installLocationPolicy(PackageInfoLite pkgLite) {
13004             String packageName = pkgLite.packageName;
13005             int installLocation = pkgLite.installLocation;
13006             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
13007             // reader
13008             synchronized (mPackages) {
13009                 // Currently installed package which the new package is attempting to replace or
13010                 // null if no such package is installed.
13011                 PackageParser.Package installedPkg = mPackages.get(packageName);
13012                 // Package which currently owns the data which the new package will own if installed.
13013                 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
13014                 // will be null whereas dataOwnerPkg will contain information about the package
13015                 // which was uninstalled while keeping its data.
13016                 PackageParser.Package dataOwnerPkg = installedPkg;
13017                 if (dataOwnerPkg  == null) {
13018                     PackageSetting ps = mSettings.mPackages.get(packageName);
13019                     if (ps != null) {
13020                         dataOwnerPkg = ps.pkg;
13021                     }
13022                 }
13023
13024                 if (dataOwnerPkg != null) {
13025                     // If installed, the package will get access to data left on the device by its
13026                     // predecessor. As a security measure, this is permited only if this is not a
13027                     // version downgrade or if the predecessor package is marked as debuggable and
13028                     // a downgrade is explicitly requested.
13029                     //
13030                     // On debuggable platform builds, downgrades are permitted even for
13031                     // non-debuggable packages to make testing easier. Debuggable platform builds do
13032                     // not offer security guarantees and thus it's OK to disable some security
13033                     // mechanisms to make debugging/testing easier on those builds. However, even on
13034                     // debuggable builds downgrades of packages are permitted only if requested via
13035                     // installFlags. This is because we aim to keep the behavior of debuggable
13036                     // platform builds as close as possible to the behavior of non-debuggable
13037                     // platform builds.
13038                     final boolean downgradeRequested =
13039                             (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
13040                     final boolean packageDebuggable =
13041                                 (dataOwnerPkg.applicationInfo.flags
13042                                         & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
13043                     final boolean downgradePermitted =
13044                             (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
13045                     if (!downgradePermitted) {
13046                         try {
13047                             checkDowngrade(dataOwnerPkg, pkgLite);
13048                         } catch (PackageManagerException e) {
13049                             Slog.w(TAG, "Downgrade detected: " + e.getMessage());
13050                             return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
13051                         }
13052                     }
13053                 }
13054
13055                 if (installedPkg != null) {
13056                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
13057                         // Check for updated system application.
13058                         if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13059                             if (onSd) {
13060                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
13061                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
13062                             }
13063                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
13064                         } else {
13065                             if (onSd) {
13066                                 // Install flag overrides everything.
13067                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
13068                             }
13069                             // If current upgrade specifies particular preference
13070                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
13071                                 // Application explicitly specified internal.
13072                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
13073                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
13074                                 // App explictly prefers external. Let policy decide
13075                             } else {
13076                                 // Prefer previous location
13077                                 if (isExternal(installedPkg)) {
13078                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
13079                                 }
13080                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
13081                             }
13082                         }
13083                     } else {
13084                         // Invalid install. Return error code
13085                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
13086                     }
13087                 }
13088             }
13089             // All the special cases have been taken care of.
13090             // Return result based on recommended install location.
13091             if (onSd) {
13092                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
13093             }
13094             return pkgLite.recommendedInstallLocation;
13095         }
13096
13097         /*
13098          * Invoke remote method to get package information and install
13099          * location values. Override install location based on default
13100          * policy if needed and then create install arguments based
13101          * on the install location.
13102          */
13103         public void handleStartCopy() throws RemoteException {
13104             int ret = PackageManager.INSTALL_SUCCEEDED;
13105
13106             // If we're already staged, we've firmly committed to an install location
13107             if (origin.staged) {
13108                 if (origin.file != null) {
13109                     installFlags |= PackageManager.INSTALL_INTERNAL;
13110                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
13111                 } else if (origin.cid != null) {
13112                     installFlags |= PackageManager.INSTALL_EXTERNAL;
13113                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
13114                 } else {
13115                     throw new IllegalStateException("Invalid stage location");
13116                 }
13117             }
13118
13119             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
13120             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
13121             final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13122             PackageInfoLite pkgLite = null;
13123
13124             if (onInt && onSd) {
13125                 // Check if both bits are set.
13126                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
13127                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
13128             } else if (onSd && ephemeral) {
13129                 Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
13130                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
13131             } else {
13132                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
13133                         packageAbiOverride);
13134
13135                 if (DEBUG_EPHEMERAL && ephemeral) {
13136                     Slog.v(TAG, "pkgLite for install: " + pkgLite);
13137                 }
13138
13139                 /*
13140                  * If we have too little free space, try to free cache
13141                  * before giving up.
13142                  */
13143                 if (!origin.staged && pkgLite.recommendedInstallLocation
13144                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
13145                     // TODO: focus freeing disk space on the target device
13146                     final StorageManager storage = StorageManager.from(mContext);
13147                     final long lowThreshold = storage.getStorageLowBytes(
13148                             Environment.getDataDirectory());
13149
13150                     final long sizeBytes = mContainerService.calculateInstalledSize(
13151                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
13152
13153                     try {
13154                         mInstaller.freeCache(null, sizeBytes + lowThreshold);
13155                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
13156                                 installFlags, packageAbiOverride);
13157                     } catch (InstallerException e) {
13158                         Slog.w(TAG, "Failed to free cache", e);
13159                     }
13160
13161                     /*
13162                      * The cache free must have deleted the file we
13163                      * downloaded to install.
13164                      *
13165                      * TODO: fix the "freeCache" call to not delete
13166                      *       the file we care about.
13167                      */
13168                     if (pkgLite.recommendedInstallLocation
13169                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
13170                         pkgLite.recommendedInstallLocation
13171                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
13172                     }
13173                 }
13174             }
13175
13176             if (ret == PackageManager.INSTALL_SUCCEEDED) {
13177                 int loc = pkgLite.recommendedInstallLocation;
13178                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
13179                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
13180                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
13181                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
13182                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
13183                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
13184                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
13185                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
13186                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
13187                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
13188                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
13189                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
13190                 } else {
13191                     // Override with defaults if needed.
13192                     loc = installLocationPolicy(pkgLite);
13193                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
13194                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
13195                     } else if (!onSd && !onInt) {
13196                         // Override install location with flags
13197                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
13198                             // Set the flag to install on external media.
13199                             installFlags |= PackageManager.INSTALL_EXTERNAL;
13200                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
13201                         } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
13202                             if (DEBUG_EPHEMERAL) {
13203                                 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
13204                             }
13205                             installFlags |= PackageManager.INSTALL_EPHEMERAL;
13206                             installFlags &= ~(PackageManager.INSTALL_EXTERNAL
13207                                     |PackageManager.INSTALL_INTERNAL);
13208                         } else {
13209                             // Make sure the flag for installing on external
13210                             // media is unset
13211                             installFlags |= PackageManager.INSTALL_INTERNAL;
13212                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
13213                         }
13214                     }
13215                 }
13216             }
13217
13218             final InstallArgs args = createInstallArgs(this);
13219             mArgs = args;
13220
13221             if (ret == PackageManager.INSTALL_SUCCEEDED) {
13222                 // TODO: http://b/22976637
13223                 // Apps installed for "all" users use the device owner to verify the app
13224                 UserHandle verifierUser = getUser();
13225                 if (verifierUser == UserHandle.ALL) {
13226                     verifierUser = UserHandle.SYSTEM;
13227                 }
13228
13229                 /*
13230                  * Determine if we have any installed package verifiers. If we
13231                  * do, then we'll defer to them to verify the packages.
13232                  */
13233                 final int requiredUid = mRequiredVerifierPackage == null ? -1
13234                         : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
13235                                 verifierUser.getIdentifier());
13236                 if (!origin.existing && requiredUid != -1
13237                         && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
13238                     final Intent verification = new Intent(
13239                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
13240                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13241                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
13242                             PACKAGE_MIME_TYPE);
13243                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13244
13245                     // Query all live verifiers based on current user state
13246                     final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
13247                             PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
13248
13249                     if (DEBUG_VERIFY) {
13250                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
13251                                 + verification.toString() + " with " + pkgLite.verifiers.length
13252                                 + " optional verifiers");
13253                     }
13254
13255                     final int verificationId = mPendingVerificationToken++;
13256
13257                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13258
13259                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
13260                             installerPackageName);
13261
13262                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
13263                             installFlags);
13264
13265                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
13266                             pkgLite.packageName);
13267
13268                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
13269                             pkgLite.versionCode);
13270
13271                     if (verificationInfo != null) {
13272                         if (verificationInfo.originatingUri != null) {
13273                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
13274                                     verificationInfo.originatingUri);
13275                         }
13276                         if (verificationInfo.referrer != null) {
13277                             verification.putExtra(Intent.EXTRA_REFERRER,
13278                                     verificationInfo.referrer);
13279                         }
13280                         if (verificationInfo.originatingUid >= 0) {
13281                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
13282                                     verificationInfo.originatingUid);
13283                         }
13284                         if (verificationInfo.installerUid >= 0) {
13285                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
13286                                     verificationInfo.installerUid);
13287                         }
13288                     }
13289
13290                     final PackageVerificationState verificationState = new PackageVerificationState(
13291                             requiredUid, args);
13292
13293                     mPendingVerification.append(verificationId, verificationState);
13294
13295                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
13296                             receivers, verificationState);
13297
13298                     /*
13299                      * If any sufficient verifiers were listed in the package
13300                      * manifest, attempt to ask them.
13301                      */
13302                     if (sufficientVerifiers != null) {
13303                         final int N = sufficientVerifiers.size();
13304                         if (N == 0) {
13305                             Slog.i(TAG, "Additional verifiers required, but none installed.");
13306                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
13307                         } else {
13308                             for (int i = 0; i < N; i++) {
13309                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
13310
13311                                 final Intent sufficientIntent = new Intent(verification);
13312                                 sufficientIntent.setComponent(verifierComponent);
13313                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
13314                             }
13315                         }
13316                     }
13317
13318                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
13319                             mRequiredVerifierPackage, receivers);
13320                     if (ret == PackageManager.INSTALL_SUCCEEDED
13321                             && mRequiredVerifierPackage != null) {
13322                         Trace.asyncTraceBegin(
13323                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
13324                         /*
13325                          * Send the intent to the required verification agent,
13326                          * but only start the verification timeout after the
13327                          * target BroadcastReceivers have run.
13328                          */
13329                         verification.setComponent(requiredVerifierComponent);
13330                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
13331                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13332                                 new BroadcastReceiver() {
13333                                     @Override
13334                                     public void onReceive(Context context, Intent intent) {
13335                                         final Message msg = mHandler
13336                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
13337                                         msg.arg1 = verificationId;
13338                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
13339                                     }
13340                                 }, null, 0, null, null);
13341
13342                         /*
13343                          * We don't want the copy to proceed until verification
13344                          * succeeds, so null out this field.
13345                          */
13346                         mArgs = null;
13347                     }
13348                 } else {
13349                     /*
13350                      * No package verification is enabled, so immediately start
13351                      * the remote call to initiate copy using temporary file.
13352                      */
13353                     ret = args.copyApk(mContainerService, true);
13354                 }
13355             }
13356
13357             mRet = ret;
13358         }
13359
13360         @Override
13361         void handleReturnCode() {
13362             // If mArgs is null, then MCS couldn't be reached. When it
13363             // reconnects, it will try again to install. At that point, this
13364             // will succeed.
13365             if (mArgs != null) {
13366                 processPendingInstall(mArgs, mRet);
13367             }
13368         }
13369
13370         @Override
13371         void handleServiceError() {
13372             mArgs = createInstallArgs(this);
13373             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13374         }
13375
13376         public boolean isForwardLocked() {
13377             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13378         }
13379     }
13380
13381     /**
13382      * Used during creation of InstallArgs
13383      *
13384      * @param installFlags package installation flags
13385      * @return true if should be installed on external storage
13386      */
13387     private static boolean installOnExternalAsec(int installFlags) {
13388         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
13389             return false;
13390         }
13391         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13392             return true;
13393         }
13394         return false;
13395     }
13396
13397     /**
13398      * Used during creation of InstallArgs
13399      *
13400      * @param installFlags package installation flags
13401      * @return true if should be installed as forward locked
13402      */
13403     private static boolean installForwardLocked(int installFlags) {
13404         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13405     }
13406
13407     private InstallArgs createInstallArgs(InstallParams params) {
13408         if (params.move != null) {
13409             return new MoveInstallArgs(params);
13410         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
13411             return new AsecInstallArgs(params);
13412         } else {
13413             return new FileInstallArgs(params);
13414         }
13415     }
13416
13417     /**
13418      * Create args that describe an existing installed package. Typically used
13419      * when cleaning up old installs, or used as a move source.
13420      */
13421     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
13422             String resourcePath, String[] instructionSets) {
13423         final boolean isInAsec;
13424         if (installOnExternalAsec(installFlags)) {
13425             /* Apps on SD card are always in ASEC containers. */
13426             isInAsec = true;
13427         } else if (installForwardLocked(installFlags)
13428                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
13429             /*
13430              * Forward-locked apps are only in ASEC containers if they're the
13431              * new style
13432              */
13433             isInAsec = true;
13434         } else {
13435             isInAsec = false;
13436         }
13437
13438         if (isInAsec) {
13439             return new AsecInstallArgs(codePath, instructionSets,
13440                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
13441         } else {
13442             return new FileInstallArgs(codePath, resourcePath, instructionSets);
13443         }
13444     }
13445
13446     static abstract class InstallArgs {
13447         /** @see InstallParams#origin */
13448         final OriginInfo origin;
13449         /** @see InstallParams#move */
13450         final MoveInfo move;
13451
13452         final IPackageInstallObserver2 observer;
13453         // Always refers to PackageManager flags only
13454         final int installFlags;
13455         final String installerPackageName;
13456         final String volumeUuid;
13457         final UserHandle user;
13458         final String abiOverride;
13459         final String[] installGrantPermissions;
13460         /** If non-null, drop an async trace when the install completes */
13461         final String traceMethod;
13462         final int traceCookie;
13463         final Certificate[][] certificates;
13464
13465         // The list of instruction sets supported by this app. This is currently
13466         // only used during the rmdex() phase to clean up resources. We can get rid of this
13467         // if we move dex files under the common app path.
13468         /* nullable */ String[] instructionSets;
13469
13470         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
13471                 int installFlags, String installerPackageName, String volumeUuid,
13472                 UserHandle user, String[] instructionSets,
13473                 String abiOverride, String[] installGrantPermissions,
13474                 String traceMethod, int traceCookie, Certificate[][] certificates) {
13475             this.origin = origin;
13476             this.move = move;
13477             this.installFlags = installFlags;
13478             this.observer = observer;
13479             this.installerPackageName = installerPackageName;
13480             this.volumeUuid = volumeUuid;
13481             this.user = user;
13482             this.instructionSets = instructionSets;
13483             this.abiOverride = abiOverride;
13484             this.installGrantPermissions = installGrantPermissions;
13485             this.traceMethod = traceMethod;
13486             this.traceCookie = traceCookie;
13487             this.certificates = certificates;
13488         }
13489
13490         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
13491         abstract int doPreInstall(int status);
13492
13493         /**
13494          * Rename package into final resting place. All paths on the given
13495          * scanned package should be updated to reflect the rename.
13496          */
13497         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
13498         abstract int doPostInstall(int status, int uid);
13499
13500         /** @see PackageSettingBase#codePathString */
13501         abstract String getCodePath();
13502         /** @see PackageSettingBase#resourcePathString */
13503         abstract String getResourcePath();
13504
13505         // Need installer lock especially for dex file removal.
13506         abstract void cleanUpResourcesLI();
13507         abstract boolean doPostDeleteLI(boolean delete);
13508
13509         /**
13510          * Called before the source arguments are copied. This is used mostly
13511          * for MoveParams when it needs to read the source file to put it in the
13512          * destination.
13513          */
13514         int doPreCopy() {
13515             return PackageManager.INSTALL_SUCCEEDED;
13516         }
13517
13518         /**
13519          * Called after the source arguments are copied. This is used mostly for
13520          * MoveParams when it needs to read the source file to put it in the
13521          * destination.
13522          */
13523         int doPostCopy(int uid) {
13524             return PackageManager.INSTALL_SUCCEEDED;
13525         }
13526
13527         protected boolean isFwdLocked() {
13528             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13529         }
13530
13531         protected boolean isExternalAsec() {
13532             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
13533         }
13534
13535         protected boolean isEphemeral() {
13536             return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13537         }
13538
13539         UserHandle getUser() {
13540             return user;
13541         }
13542     }
13543
13544     private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
13545         if (!allCodePaths.isEmpty()) {
13546             if (instructionSets == null) {
13547                 throw new IllegalStateException("instructionSet == null");
13548             }
13549             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
13550             for (String codePath : allCodePaths) {
13551                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
13552                     try {
13553                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
13554                     } catch (InstallerException ignored) {
13555                     }
13556                 }
13557             }
13558         }
13559     }
13560
13561     /**
13562      * Logic to handle installation of non-ASEC applications, including copying
13563      * and renaming logic.
13564      */
13565     class FileInstallArgs extends InstallArgs {
13566         private File codeFile;
13567         private File resourceFile;
13568
13569         // Example topology:
13570         // /data/app/com.example/base.apk
13571         // /data/app/com.example/split_foo.apk
13572         // /data/app/com.example/lib/arm/libfoo.so
13573         // /data/app/com.example/lib/arm64/libfoo.so
13574         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
13575
13576         /** New install */
13577         FileInstallArgs(InstallParams params) {
13578             super(params.origin, params.move, params.observer, params.installFlags,
13579                     params.installerPackageName, params.volumeUuid,
13580                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
13581                     params.grantedRuntimePermissions,
13582                     params.traceMethod, params.traceCookie, params.certificates);
13583             if (isFwdLocked()) {
13584                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
13585             }
13586         }
13587
13588         /** Existing install */
13589         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
13590             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
13591                     null, null, null, 0, null /*certificates*/);
13592             this.codeFile = (codePath != null) ? new File(codePath) : null;
13593             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
13594         }
13595
13596         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13597             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
13598             try {
13599                 return doCopyApk(imcs, temp);
13600             } finally {
13601                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13602             }
13603         }
13604
13605         private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13606             if (origin.staged) {
13607                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
13608                 codeFile = origin.file;
13609                 resourceFile = origin.file;
13610                 return PackageManager.INSTALL_SUCCEEDED;
13611             }
13612
13613             try {
13614                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13615                 final File tempDir =
13616                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
13617                 codeFile = tempDir;
13618                 resourceFile = tempDir;
13619             } catch (IOException e) {
13620                 Slog.w(TAG, "Failed to create copy file: " + e);
13621                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
13622             }
13623
13624             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
13625                 @Override
13626                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
13627                     if (!FileUtils.isValidExtFilename(name)) {
13628                         throw new IllegalArgumentException("Invalid filename: " + name);
13629                     }
13630                     try {
13631                         final File file = new File(codeFile, name);
13632                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
13633                                 O_RDWR | O_CREAT, 0644);
13634                         Os.chmod(file.getAbsolutePath(), 0644);
13635                         return new ParcelFileDescriptor(fd);
13636                     } catch (ErrnoException e) {
13637                         throw new RemoteException("Failed to open: " + e.getMessage());
13638                     }
13639                 }
13640             };
13641
13642             int ret = PackageManager.INSTALL_SUCCEEDED;
13643             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
13644             if (ret != PackageManager.INSTALL_SUCCEEDED) {
13645                 Slog.e(TAG, "Failed to copy package");
13646                 return ret;
13647             }
13648
13649             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
13650             NativeLibraryHelper.Handle handle = null;
13651             try {
13652                 handle = NativeLibraryHelper.Handle.create(codeFile);
13653                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
13654                         abiOverride);
13655             } catch (IOException e) {
13656                 Slog.e(TAG, "Copying native libraries failed", e);
13657                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13658             } finally {
13659                 IoUtils.closeQuietly(handle);
13660             }
13661
13662             return ret;
13663         }
13664
13665         int doPreInstall(int status) {
13666             if (status != PackageManager.INSTALL_SUCCEEDED) {
13667                 cleanUp();
13668             }
13669             return status;
13670         }
13671
13672         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13673             if (status != PackageManager.INSTALL_SUCCEEDED) {
13674                 cleanUp();
13675                 return false;
13676             }
13677
13678             final File targetDir = codeFile.getParentFile();
13679             final File beforeCodeFile = codeFile;
13680             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
13681
13682             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
13683             try {
13684                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
13685             } catch (ErrnoException e) {
13686                 Slog.w(TAG, "Failed to rename", e);
13687                 return false;
13688             }
13689
13690             if (!SELinux.restoreconRecursive(afterCodeFile)) {
13691                 Slog.w(TAG, "Failed to restorecon");
13692                 return false;
13693             }
13694
13695             // Reflect the rename internally
13696             codeFile = afterCodeFile;
13697             resourceFile = afterCodeFile;
13698
13699             // Reflect the rename in scanned details
13700             pkg.setCodePath(afterCodeFile.getAbsolutePath());
13701             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13702                     afterCodeFile, pkg.baseCodePath));
13703             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13704                     afterCodeFile, pkg.splitCodePaths));
13705
13706             // Reflect the rename in app info
13707             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13708             pkg.setApplicationInfoCodePath(pkg.codePath);
13709             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13710             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13711             pkg.setApplicationInfoResourcePath(pkg.codePath);
13712             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13713             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13714
13715             return true;
13716         }
13717
13718         int doPostInstall(int status, int uid) {
13719             if (status != PackageManager.INSTALL_SUCCEEDED) {
13720                 cleanUp();
13721             }
13722             return status;
13723         }
13724
13725         @Override
13726         String getCodePath() {
13727             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
13728         }
13729
13730         @Override
13731         String getResourcePath() {
13732             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
13733         }
13734
13735         private boolean cleanUp() {
13736             if (codeFile == null || !codeFile.exists()) {
13737                 return false;
13738             }
13739
13740             removeCodePathLI(codeFile);
13741
13742             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
13743                 resourceFile.delete();
13744             }
13745
13746             return true;
13747         }
13748
13749         void cleanUpResourcesLI() {
13750             // Try enumerating all code paths before deleting
13751             List<String> allCodePaths = Collections.EMPTY_LIST;
13752             if (codeFile != null && codeFile.exists()) {
13753                 try {
13754                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
13755                     allCodePaths = pkg.getAllCodePaths();
13756                 } catch (PackageParserException e) {
13757                     // Ignored; we tried our best
13758                 }
13759             }
13760
13761             cleanUp();
13762             removeDexFiles(allCodePaths, instructionSets);
13763         }
13764
13765         boolean doPostDeleteLI(boolean delete) {
13766             // XXX err, shouldn't we respect the delete flag?
13767             cleanUpResourcesLI();
13768             return true;
13769         }
13770     }
13771
13772     private boolean isAsecExternal(String cid) {
13773         final String asecPath = PackageHelper.getSdFilesystem(cid);
13774         return !asecPath.startsWith(mAsecInternalPath);
13775     }
13776
13777     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
13778             PackageManagerException {
13779         if (copyRet < 0) {
13780             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
13781                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
13782                 throw new PackageManagerException(copyRet, message);
13783             }
13784         }
13785     }
13786
13787     /**
13788      * Extract the MountService "container ID" from the full code path of an
13789      * .apk.
13790      */
13791     static String cidFromCodePath(String fullCodePath) {
13792         int eidx = fullCodePath.lastIndexOf("/");
13793         String subStr1 = fullCodePath.substring(0, eidx);
13794         int sidx = subStr1.lastIndexOf("/");
13795         return subStr1.substring(sidx+1, eidx);
13796     }
13797
13798     /**
13799      * Logic to handle installation of ASEC applications, including copying and
13800      * renaming logic.
13801      */
13802     class AsecInstallArgs extends InstallArgs {
13803         static final String RES_FILE_NAME = "pkg.apk";
13804         static final String PUBLIC_RES_FILE_NAME = "res.zip";
13805
13806         String cid;
13807         String packagePath;
13808         String resourcePath;
13809
13810         /** New install */
13811         AsecInstallArgs(InstallParams params) {
13812             super(params.origin, params.move, params.observer, params.installFlags,
13813                     params.installerPackageName, params.volumeUuid,
13814                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
13815                     params.grantedRuntimePermissions,
13816                     params.traceMethod, params.traceCookie, params.certificates);
13817         }
13818
13819         /** Existing install */
13820         AsecInstallArgs(String fullCodePath, String[] instructionSets,
13821                         boolean isExternal, boolean isForwardLocked) {
13822             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
13823               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13824                     instructionSets, null, null, null, 0, null /*certificates*/);
13825             // Hackily pretend we're still looking at a full code path
13826             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
13827                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
13828             }
13829
13830             // Extract cid from fullCodePath
13831             int eidx = fullCodePath.lastIndexOf("/");
13832             String subStr1 = fullCodePath.substring(0, eidx);
13833             int sidx = subStr1.lastIndexOf("/");
13834             cid = subStr1.substring(sidx+1, eidx);
13835             setMountPath(subStr1);
13836         }
13837
13838         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
13839             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
13840               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13841                     instructionSets, null, null, null, 0, null /*certificates*/);
13842             this.cid = cid;
13843             setMountPath(PackageHelper.getSdDir(cid));
13844         }
13845
13846         void createCopyFile() {
13847             cid = mInstallerService.allocateExternalStageCidLegacy();
13848         }
13849
13850         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13851             if (origin.staged && origin.cid != null) {
13852                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
13853                 cid = origin.cid;
13854                 setMountPath(PackageHelper.getSdDir(cid));
13855                 return PackageManager.INSTALL_SUCCEEDED;
13856             }
13857
13858             if (temp) {
13859                 createCopyFile();
13860             } else {
13861                 /*
13862                  * Pre-emptively destroy the container since it's destroyed if
13863                  * copying fails due to it existing anyway.
13864                  */
13865                 PackageHelper.destroySdDir(cid);
13866             }
13867
13868             final String newMountPath = imcs.copyPackageToContainer(
13869                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
13870                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
13871
13872             if (newMountPath != null) {
13873                 setMountPath(newMountPath);
13874                 return PackageManager.INSTALL_SUCCEEDED;
13875             } else {
13876                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13877             }
13878         }
13879
13880         @Override
13881         String getCodePath() {
13882             return packagePath;
13883         }
13884
13885         @Override
13886         String getResourcePath() {
13887             return resourcePath;
13888         }
13889
13890         int doPreInstall(int status) {
13891             if (status != PackageManager.INSTALL_SUCCEEDED) {
13892                 // Destroy container
13893                 PackageHelper.destroySdDir(cid);
13894             } else {
13895                 boolean mounted = PackageHelper.isContainerMounted(cid);
13896                 if (!mounted) {
13897                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
13898                             Process.SYSTEM_UID);
13899                     if (newMountPath != null) {
13900                         setMountPath(newMountPath);
13901                     } else {
13902                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13903                     }
13904                 }
13905             }
13906             return status;
13907         }
13908
13909         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13910             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
13911             String newMountPath = null;
13912             if (PackageHelper.isContainerMounted(cid)) {
13913                 // Unmount the container
13914                 if (!PackageHelper.unMountSdDir(cid)) {
13915                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
13916                     return false;
13917                 }
13918             }
13919             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13920                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
13921                         " which might be stale. Will try to clean up.");
13922                 // Clean up the stale container and proceed to recreate.
13923                 if (!PackageHelper.destroySdDir(newCacheId)) {
13924                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
13925                     return false;
13926                 }
13927                 // Successfully cleaned up stale container. Try to rename again.
13928                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13929                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
13930                             + " inspite of cleaning it up.");
13931                     return false;
13932                 }
13933             }
13934             if (!PackageHelper.isContainerMounted(newCacheId)) {
13935                 Slog.w(TAG, "Mounting container " + newCacheId);
13936                 newMountPath = PackageHelper.mountSdDir(newCacheId,
13937                         getEncryptKey(), Process.SYSTEM_UID);
13938             } else {
13939                 newMountPath = PackageHelper.getSdDir(newCacheId);
13940             }
13941             if (newMountPath == null) {
13942                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
13943                 return false;
13944             }
13945             Log.i(TAG, "Succesfully renamed " + cid +
13946                     " to " + newCacheId +
13947                     " at new path: " + newMountPath);
13948             cid = newCacheId;
13949
13950             final File beforeCodeFile = new File(packagePath);
13951             setMountPath(newMountPath);
13952             final File afterCodeFile = new File(packagePath);
13953
13954             // Reflect the rename in scanned details
13955             pkg.setCodePath(afterCodeFile.getAbsolutePath());
13956             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13957                     afterCodeFile, pkg.baseCodePath));
13958             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13959                     afterCodeFile, pkg.splitCodePaths));
13960
13961             // Reflect the rename in app info
13962             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13963             pkg.setApplicationInfoCodePath(pkg.codePath);
13964             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13965             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13966             pkg.setApplicationInfoResourcePath(pkg.codePath);
13967             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13968             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13969
13970             return true;
13971         }
13972
13973         private void setMountPath(String mountPath) {
13974             final File mountFile = new File(mountPath);
13975
13976             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
13977             if (monolithicFile.exists()) {
13978                 packagePath = monolithicFile.getAbsolutePath();
13979                 if (isFwdLocked()) {
13980                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
13981                 } else {
13982                     resourcePath = packagePath;
13983                 }
13984             } else {
13985                 packagePath = mountFile.getAbsolutePath();
13986                 resourcePath = packagePath;
13987             }
13988         }
13989
13990         int doPostInstall(int status, int uid) {
13991             if (status != PackageManager.INSTALL_SUCCEEDED) {
13992                 cleanUp();
13993             } else {
13994                 final int groupOwner;
13995                 final String protectedFile;
13996                 if (isFwdLocked()) {
13997                     groupOwner = UserHandle.getSharedAppGid(uid);
13998                     protectedFile = RES_FILE_NAME;
13999                 } else {
14000                     groupOwner = -1;
14001                     protectedFile = null;
14002                 }
14003
14004                 if (uid < Process.FIRST_APPLICATION_UID
14005                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
14006                     Slog.e(TAG, "Failed to finalize " + cid);
14007                     PackageHelper.destroySdDir(cid);
14008                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
14009                 }
14010
14011                 boolean mounted = PackageHelper.isContainerMounted(cid);
14012                 if (!mounted) {
14013                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
14014                 }
14015             }
14016             return status;
14017         }
14018
14019         private void cleanUp() {
14020             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
14021
14022             // Destroy secure container
14023             PackageHelper.destroySdDir(cid);
14024         }
14025
14026         private List<String> getAllCodePaths() {
14027             final File codeFile = new File(getCodePath());
14028             if (codeFile != null && codeFile.exists()) {
14029                 try {
14030                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
14031                     return pkg.getAllCodePaths();
14032                 } catch (PackageParserException e) {
14033                     // Ignored; we tried our best
14034                 }
14035             }
14036             return Collections.EMPTY_LIST;
14037         }
14038
14039         void cleanUpResourcesLI() {
14040             // Enumerate all code paths before deleting
14041             cleanUpResourcesLI(getAllCodePaths());
14042         }
14043
14044         private void cleanUpResourcesLI(List<String> allCodePaths) {
14045             cleanUp();
14046             removeDexFiles(allCodePaths, instructionSets);
14047         }
14048
14049         String getPackageName() {
14050             return getAsecPackageName(cid);
14051         }
14052
14053         boolean doPostDeleteLI(boolean delete) {
14054             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
14055             final List<String> allCodePaths = getAllCodePaths();
14056             boolean mounted = PackageHelper.isContainerMounted(cid);
14057             if (mounted) {
14058                 // Unmount first
14059                 if (PackageHelper.unMountSdDir(cid)) {
14060                     mounted = false;
14061                 }
14062             }
14063             if (!mounted && delete) {
14064                 cleanUpResourcesLI(allCodePaths);
14065             }
14066             return !mounted;
14067         }
14068
14069         @Override
14070         int doPreCopy() {
14071             if (isFwdLocked()) {
14072                 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
14073                         MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
14074                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
14075                 }
14076             }
14077
14078             return PackageManager.INSTALL_SUCCEEDED;
14079         }
14080
14081         @Override
14082         int doPostCopy(int uid) {
14083             if (isFwdLocked()) {
14084                 if (uid < Process.FIRST_APPLICATION_UID
14085                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
14086                                 RES_FILE_NAME)) {
14087                     Slog.e(TAG, "Failed to finalize " + cid);
14088                     PackageHelper.destroySdDir(cid);
14089                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
14090                 }
14091             }
14092
14093             return PackageManager.INSTALL_SUCCEEDED;
14094         }
14095     }
14096
14097     /**
14098      * Logic to handle movement of existing installed applications.
14099      */
14100     class MoveInstallArgs extends InstallArgs {
14101         private File codeFile;
14102         private File resourceFile;
14103
14104         /** New install */
14105         MoveInstallArgs(InstallParams params) {
14106             super(params.origin, params.move, params.observer, params.installFlags,
14107                     params.installerPackageName, params.volumeUuid,
14108                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
14109                     params.grantedRuntimePermissions,
14110                     params.traceMethod, params.traceCookie, params.certificates);
14111         }
14112
14113         int copyApk(IMediaContainerService imcs, boolean temp) {
14114             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
14115                     + move.fromUuid + " to " + move.toUuid);
14116             synchronized (mInstaller) {
14117                 try {
14118                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
14119                             move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
14120                 } catch (InstallerException e) {
14121                     Slog.w(TAG, "Failed to move app", e);
14122                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14123                 }
14124             }
14125
14126             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
14127             resourceFile = codeFile;
14128             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
14129
14130             return PackageManager.INSTALL_SUCCEEDED;
14131         }
14132
14133         int doPreInstall(int status) {
14134             if (status != PackageManager.INSTALL_SUCCEEDED) {
14135                 cleanUp(move.toUuid);
14136             }
14137             return status;
14138         }
14139
14140         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
14141             if (status != PackageManager.INSTALL_SUCCEEDED) {
14142                 cleanUp(move.toUuid);
14143                 return false;
14144             }
14145
14146             // Reflect the move in app info
14147             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
14148             pkg.setApplicationInfoCodePath(pkg.codePath);
14149             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
14150             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
14151             pkg.setApplicationInfoResourcePath(pkg.codePath);
14152             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
14153             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
14154
14155             return true;
14156         }
14157
14158         int doPostInstall(int status, int uid) {
14159             if (status == PackageManager.INSTALL_SUCCEEDED) {
14160                 cleanUp(move.fromUuid);
14161             } else {
14162                 cleanUp(move.toUuid);
14163             }
14164             return status;
14165         }
14166
14167         @Override
14168         String getCodePath() {
14169             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
14170         }
14171
14172         @Override
14173         String getResourcePath() {
14174             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
14175         }
14176
14177         private boolean cleanUp(String volumeUuid) {
14178             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
14179                     move.dataAppName);
14180             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
14181             final int[] userIds = sUserManager.getUserIds();
14182             synchronized (mInstallLock) {
14183                 // Clean up both app data and code
14184                 // All package moves are frozen until finished
14185                 for (int userId : userIds) {
14186                     try {
14187                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
14188                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
14189                     } catch (InstallerException e) {
14190                         Slog.w(TAG, String.valueOf(e));
14191                     }
14192                 }
14193                 removeCodePathLI(codeFile);
14194             }
14195             return true;
14196         }
14197
14198         void cleanUpResourcesLI() {
14199             throw new UnsupportedOperationException();
14200         }
14201
14202         boolean doPostDeleteLI(boolean delete) {
14203             throw new UnsupportedOperationException();
14204         }
14205     }
14206
14207     static String getAsecPackageName(String packageCid) {
14208         int idx = packageCid.lastIndexOf("-");
14209         if (idx == -1) {
14210             return packageCid;
14211         }
14212         return packageCid.substring(0, idx);
14213     }
14214
14215     // Utility method used to create code paths based on package name and available index.
14216     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
14217         String idxStr = "";
14218         int idx = 1;
14219         // Fall back to default value of idx=1 if prefix is not
14220         // part of oldCodePath
14221         if (oldCodePath != null) {
14222             String subStr = oldCodePath;
14223             // Drop the suffix right away
14224             if (suffix != null && subStr.endsWith(suffix)) {
14225                 subStr = subStr.substring(0, subStr.length() - suffix.length());
14226             }
14227             // If oldCodePath already contains prefix find out the
14228             // ending index to either increment or decrement.
14229             int sidx = subStr.lastIndexOf(prefix);
14230             if (sidx != -1) {
14231                 subStr = subStr.substring(sidx + prefix.length());
14232                 if (subStr != null) {
14233                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
14234                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
14235                     }
14236                     try {
14237                         idx = Integer.parseInt(subStr);
14238                         if (idx <= 1) {
14239                             idx++;
14240                         } else {
14241                             idx--;
14242                         }
14243                     } catch(NumberFormatException e) {
14244                     }
14245                 }
14246             }
14247         }
14248         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
14249         return prefix + idxStr;
14250     }
14251
14252     private File getNextCodePath(File targetDir, String packageName) {
14253         int suffix = 1;
14254         File result;
14255         do {
14256             result = new File(targetDir, packageName + "-" + suffix);
14257             suffix++;
14258         } while (result.exists());
14259         return result;
14260     }
14261
14262     // Utility method that returns the relative package path with respect
14263     // to the installation directory. Like say for /data/data/com.test-1.apk
14264     // string com.test-1 is returned.
14265     static String deriveCodePathName(String codePath) {
14266         if (codePath == null) {
14267             return null;
14268         }
14269         final File codeFile = new File(codePath);
14270         final String name = codeFile.getName();
14271         if (codeFile.isDirectory()) {
14272             return name;
14273         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
14274             final int lastDot = name.lastIndexOf('.');
14275             return name.substring(0, lastDot);
14276         } else {
14277             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
14278             return null;
14279         }
14280     }
14281
14282     static class PackageInstalledInfo {
14283         String name;
14284         int uid;
14285         // The set of users that originally had this package installed.
14286         int[] origUsers;
14287         // The set of users that now have this package installed.
14288         int[] newUsers;
14289         PackageParser.Package pkg;
14290         int returnCode;
14291         String returnMsg;
14292         PackageRemovedInfo removedInfo;
14293         ArrayMap<String, PackageInstalledInfo> addedChildPackages;
14294
14295         public void setError(int code, String msg) {
14296             setReturnCode(code);
14297             setReturnMessage(msg);
14298             Slog.w(TAG, msg);
14299         }
14300
14301         public void setError(String msg, PackageParserException e) {
14302             setReturnCode(e.error);
14303             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
14304             Slog.w(TAG, msg, e);
14305         }
14306
14307         public void setError(String msg, PackageManagerException e) {
14308             returnCode = e.error;
14309             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
14310             Slog.w(TAG, msg, e);
14311         }
14312
14313         public void setReturnCode(int returnCode) {
14314             this.returnCode = returnCode;
14315             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
14316             for (int i = 0; i < childCount; i++) {
14317                 addedChildPackages.valueAt(i).returnCode = returnCode;
14318             }
14319         }
14320
14321         private void setReturnMessage(String returnMsg) {
14322             this.returnMsg = returnMsg;
14323             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
14324             for (int i = 0; i < childCount; i++) {
14325                 addedChildPackages.valueAt(i).returnMsg = returnMsg;
14326             }
14327         }
14328
14329         // In some error cases we want to convey more info back to the observer
14330         String origPackage;
14331         String origPermission;
14332     }
14333
14334     /*
14335      * Install a non-existing package.
14336      */
14337     private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
14338             int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
14339             PackageInstalledInfo res) {
14340         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
14341
14342         // Remember this for later, in case we need to rollback this install
14343         String pkgName = pkg.packageName;
14344
14345         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
14346
14347         synchronized(mPackages) {
14348             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
14349                 // A package with the same name is already installed, though
14350                 // it has been renamed to an older name.  The package we
14351                 // are trying to install should be installed as an update to
14352                 // the existing one, but that has not been requested, so bail.
14353                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
14354                         + " without first uninstalling package running as "
14355                         + mSettings.mRenamedPackages.get(pkgName));
14356                 return;
14357             }
14358             if (mPackages.containsKey(pkgName)) {
14359                 // Don't allow installation over an existing package with the same name.
14360                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
14361                         + " without first uninstalling.");
14362                 return;
14363             }
14364         }
14365
14366         try {
14367             PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
14368                     System.currentTimeMillis(), user);
14369
14370             updateSettingsLI(newPackage, installerPackageName, null, res, user);
14371
14372             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14373                 prepareAppDataAfterInstallLIF(newPackage);
14374
14375             } else {
14376                 // Remove package from internal structures, but keep around any
14377                 // data that might have already existed
14378                 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
14379                         PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
14380             }
14381         } catch (PackageManagerException e) {
14382             res.setError("Package couldn't be installed in " + pkg.codePath, e);
14383         }
14384
14385         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14386     }
14387
14388     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
14389         // Can't rotate keys during boot or if sharedUser.
14390         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
14391                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
14392             return false;
14393         }
14394         // app is using upgradeKeySets; make sure all are valid
14395         KeySetManagerService ksms = mSettings.mKeySetManagerService;
14396         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
14397         for (int i = 0; i < upgradeKeySets.length; i++) {
14398             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
14399                 Slog.wtf(TAG, "Package "
14400                          + (oldPs.name != null ? oldPs.name : "<null>")
14401                          + " contains upgrade-key-set reference to unknown key-set: "
14402                          + upgradeKeySets[i]
14403                          + " reverting to signatures check.");
14404                 return false;
14405             }
14406         }
14407         return true;
14408     }
14409
14410     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
14411         // Upgrade keysets are being used.  Determine if new package has a superset of the
14412         // required keys.
14413         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
14414         KeySetManagerService ksms = mSettings.mKeySetManagerService;
14415         for (int i = 0; i < upgradeKeySets.length; i++) {
14416             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
14417             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
14418                 return true;
14419             }
14420         }
14421         return false;
14422     }
14423
14424     private static void updateDigest(MessageDigest digest, File file) throws IOException {
14425         try (DigestInputStream digestStream =
14426                 new DigestInputStream(new FileInputStream(file), digest)) {
14427             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
14428         }
14429     }
14430
14431     private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
14432             UserHandle user, String installerPackageName, PackageInstalledInfo res) {
14433         final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
14434
14435         final PackageParser.Package oldPackage;
14436         final String pkgName = pkg.packageName;
14437         final int[] allUsers;
14438         final int[] installedUsers;
14439
14440         synchronized(mPackages) {
14441             oldPackage = mPackages.get(pkgName);
14442             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
14443
14444             // don't allow upgrade to target a release SDK from a pre-release SDK
14445             final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
14446                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14447             final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
14448                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14449             if (oldTargetsPreRelease
14450                     && !newTargetsPreRelease
14451                     && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
14452                 Slog.w(TAG, "Can't install package targeting released sdk");
14453                 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
14454                 return;
14455             }
14456
14457             // don't allow an upgrade from full to ephemeral
14458             final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
14459             if (isEphemeral && !oldIsEphemeral) {
14460                 // can't downgrade from full to ephemeral
14461                 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
14462                 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
14463                 return;
14464             }
14465
14466             // verify signatures are valid
14467             final PackageSetting ps = mSettings.mPackages.get(pkgName);
14468             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
14469                 if (!checkUpgradeKeySetLP(ps, pkg)) {
14470                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14471                             "New package not signed by keys specified by upgrade-keysets: "
14472                                     + pkgName);
14473                     return;
14474                 }
14475             } else {
14476                 // default to original signature matching
14477                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
14478                         != PackageManager.SIGNATURE_MATCH) {
14479                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14480                             "New package has a different signature: " + pkgName);
14481                     return;
14482                 }
14483             }
14484
14485             // don't allow a system upgrade unless the upgrade hash matches
14486             if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
14487                 byte[] digestBytes = null;
14488                 try {
14489                     final MessageDigest digest = MessageDigest.getInstance("SHA-512");
14490                     updateDigest(digest, new File(pkg.baseCodePath));
14491                     if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
14492                         for (String path : pkg.splitCodePaths) {
14493                             updateDigest(digest, new File(path));
14494                         }
14495                     }
14496                     digestBytes = digest.digest();
14497                 } catch (NoSuchAlgorithmException | IOException e) {
14498                     res.setError(INSTALL_FAILED_INVALID_APK,
14499                             "Could not compute hash: " + pkgName);
14500                     return;
14501                 }
14502                 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
14503                     res.setError(INSTALL_FAILED_INVALID_APK,
14504                             "New package fails restrict-update check: " + pkgName);
14505                     return;
14506                 }
14507                 // retain upgrade restriction
14508                 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
14509             }
14510
14511             // Check for shared user id changes
14512             String invalidPackageName =
14513                     getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
14514             if (invalidPackageName != null) {
14515                 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
14516                         "Package " + invalidPackageName + " tried to change user "
14517                                 + oldPackage.mSharedUserId);
14518                 return;
14519             }
14520
14521             // In case of rollback, remember per-user/profile install state
14522             allUsers = sUserManager.getUserIds();
14523             installedUsers = ps.queryInstalledUsers(allUsers, true);
14524         }
14525
14526         // Update what is removed
14527         res.removedInfo = new PackageRemovedInfo();
14528         res.removedInfo.uid = oldPackage.applicationInfo.uid;
14529         res.removedInfo.removedPackage = oldPackage.packageName;
14530         res.removedInfo.isUpdate = true;
14531         res.removedInfo.origUsers = installedUsers;
14532         final int childCount = (oldPackage.childPackages != null)
14533                 ? oldPackage.childPackages.size() : 0;
14534         for (int i = 0; i < childCount; i++) {
14535             boolean childPackageUpdated = false;
14536             PackageParser.Package childPkg = oldPackage.childPackages.get(i);
14537             if (res.addedChildPackages != null) {
14538                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
14539                 if (childRes != null) {
14540                     childRes.removedInfo.uid = childPkg.applicationInfo.uid;
14541                     childRes.removedInfo.removedPackage = childPkg.packageName;
14542                     childRes.removedInfo.isUpdate = true;
14543                     childPackageUpdated = true;
14544                 }
14545             }
14546             if (!childPackageUpdated) {
14547                 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
14548                 childRemovedRes.removedPackage = childPkg.packageName;
14549                 childRemovedRes.isUpdate = false;
14550                 childRemovedRes.dataRemoved = true;
14551                 synchronized (mPackages) {
14552                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
14553                     if (childPs != null) {
14554                         childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
14555                     }
14556                 }
14557                 if (res.removedInfo.removedChildPackages == null) {
14558                     res.removedInfo.removedChildPackages = new ArrayMap<>();
14559                 }
14560                 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
14561             }
14562         }
14563
14564         boolean sysPkg = (isSystemApp(oldPackage));
14565         if (sysPkg) {
14566             // Set the system/privileged flags as needed
14567             final boolean privileged =
14568                     (oldPackage.applicationInfo.privateFlags
14569                             & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
14570             final int systemPolicyFlags = policyFlags
14571                     | PackageParser.PARSE_IS_SYSTEM
14572                     | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
14573
14574             replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
14575                     user, allUsers, installerPackageName, res);
14576         } else {
14577             replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
14578                     user, allUsers, installerPackageName, res);
14579         }
14580     }
14581
14582     public List<String> getPreviousCodePaths(String packageName) {
14583         final PackageSetting ps = mSettings.mPackages.get(packageName);
14584         final List<String> result = new ArrayList<String>();
14585         if (ps != null && ps.oldCodePaths != null) {
14586             result.addAll(ps.oldCodePaths);
14587         }
14588         return result;
14589     }
14590
14591     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
14592             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14593             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14594         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
14595                 + deletedPackage);
14596
14597         String pkgName = deletedPackage.packageName;
14598         boolean deletedPkg = true;
14599         boolean addedPkg = false;
14600         boolean updatedSettings = false;
14601         final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
14602         final int deleteFlags = PackageManager.DELETE_KEEP_DATA
14603                 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
14604
14605         final long origUpdateTime = (pkg.mExtras != null)
14606                 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
14607
14608         // First delete the existing package while retaining the data directory
14609         if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14610                 res.removedInfo, true, pkg)) {
14611             // If the existing package wasn't successfully deleted
14612             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
14613             deletedPkg = false;
14614         } else {
14615             // Successfully deleted the old package; proceed with replace.
14616
14617             // If deleted package lived in a container, give users a chance to
14618             // relinquish resources before killing.
14619             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
14620                 if (DEBUG_INSTALL) {
14621                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
14622                 }
14623                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
14624                 final ArrayList<String> pkgList = new ArrayList<String>(1);
14625                 pkgList.add(deletedPackage.applicationInfo.packageName);
14626                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
14627             }
14628
14629             clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14630                     | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14631             clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14632
14633             try {
14634                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
14635                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
14636                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14637
14638                 // Update the in-memory copy of the previous code paths.
14639                 PackageSetting ps = mSettings.mPackages.get(pkgName);
14640                 if (!killApp) {
14641                     if (ps.oldCodePaths == null) {
14642                         ps.oldCodePaths = new ArraySet<>();
14643                     }
14644                     Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
14645                     if (deletedPackage.splitCodePaths != null) {
14646                         Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
14647                     }
14648                 } else {
14649                     ps.oldCodePaths = null;
14650                 }
14651                 if (ps.childPackageNames != null) {
14652                     for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
14653                         final String childPkgName = ps.childPackageNames.get(i);
14654                         final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
14655                         childPs.oldCodePaths = ps.oldCodePaths;
14656                     }
14657                 }
14658                 prepareAppDataAfterInstallLIF(newPackage);
14659                 addedPkg = true;
14660             } catch (PackageManagerException e) {
14661                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
14662             }
14663         }
14664
14665         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14666             if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
14667
14668             // Revert all internal state mutations and added folders for the failed install
14669             if (addedPkg) {
14670                 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14671                         res.removedInfo, true, null);
14672             }
14673
14674             // Restore the old package
14675             if (deletedPkg) {
14676                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
14677                 File restoreFile = new File(deletedPackage.codePath);
14678                 // Parse old package
14679                 boolean oldExternal = isExternal(deletedPackage);
14680                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
14681                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
14682                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
14683                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
14684                 try {
14685                     scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
14686                             null);
14687                 } catch (PackageManagerException e) {
14688                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
14689                             + e.getMessage());
14690                     return;
14691                 }
14692
14693                 synchronized (mPackages) {
14694                     // Ensure the installer package name up to date
14695                     setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14696
14697                     // Update permissions for restored package
14698                     updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14699
14700                     mSettings.writeLPr();
14701                 }
14702
14703                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
14704             }
14705         } else {
14706             synchronized (mPackages) {
14707                 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName);
14708                 if (ps != null) {
14709                     res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
14710                     if (res.removedInfo.removedChildPackages != null) {
14711                         final int childCount = res.removedInfo.removedChildPackages.size();
14712                         // Iterate in reverse as we may modify the collection
14713                         for (int i = childCount - 1; i >= 0; i--) {
14714                             String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
14715                             if (res.addedChildPackages.containsKey(childPackageName)) {
14716                                 res.removedInfo.removedChildPackages.removeAt(i);
14717                             } else {
14718                                 PackageRemovedInfo childInfo = res.removedInfo
14719                                         .removedChildPackages.valueAt(i);
14720                                 childInfo.removedForAllUsers = mPackages.get(
14721                                         childInfo.removedPackage) == null;
14722                             }
14723                         }
14724                     }
14725                 }
14726             }
14727         }
14728     }
14729
14730     private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
14731             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14732             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14733         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
14734                 + ", old=" + deletedPackage);
14735
14736         final boolean disabledSystem;
14737
14738         // Remove existing system package
14739         removePackageLI(deletedPackage, true);
14740
14741         synchronized (mPackages) {
14742             disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
14743         }
14744         if (!disabledSystem) {
14745             // We didn't need to disable the .apk as a current system package,
14746             // which means we are replacing another update that is already
14747             // installed.  We need to make sure to delete the older one's .apk.
14748             res.removedInfo.args = createInstallArgsForExisting(0,
14749                     deletedPackage.applicationInfo.getCodePath(),
14750                     deletedPackage.applicationInfo.getResourcePath(),
14751                     getAppDexInstructionSets(deletedPackage.applicationInfo));
14752         } else {
14753             res.removedInfo.args = null;
14754         }
14755
14756         // Successfully disabled the old package. Now proceed with re-installation
14757         clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14758                 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14759         clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14760
14761         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14762         pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
14763                 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
14764
14765         PackageParser.Package newPackage = null;
14766         try {
14767             // Add the package to the internal data structures
14768             newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
14769
14770             // Set the update and install times
14771             PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
14772             setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
14773                     System.currentTimeMillis());
14774
14775             // Update the package dynamic state if succeeded
14776             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14777                 // Now that the install succeeded make sure we remove data
14778                 // directories for any child package the update removed.
14779                 final int deletedChildCount = (deletedPackage.childPackages != null)
14780                         ? deletedPackage.childPackages.size() : 0;
14781                 final int newChildCount = (newPackage.childPackages != null)
14782                         ? newPackage.childPackages.size() : 0;
14783                 for (int i = 0; i < deletedChildCount; i++) {
14784                     PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
14785                     boolean childPackageDeleted = true;
14786                     for (int j = 0; j < newChildCount; j++) {
14787                         PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
14788                         if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
14789                             childPackageDeleted = false;
14790                             break;
14791                         }
14792                     }
14793                     if (childPackageDeleted) {
14794                         PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
14795                                 deletedChildPkg.packageName);
14796                         if (ps != null && res.removedInfo.removedChildPackages != null) {
14797                             PackageRemovedInfo removedChildRes = res.removedInfo
14798                                     .removedChildPackages.get(deletedChildPkg.packageName);
14799                             removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
14800                             removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
14801                         }
14802                     }
14803                 }
14804
14805                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14806                 prepareAppDataAfterInstallLIF(newPackage);
14807             }
14808         } catch (PackageManagerException e) {
14809             res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
14810             res.setError("Package couldn't be installed in " + pkg.codePath, e);
14811         }
14812
14813         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14814             // Re installation failed. Restore old information
14815             // Remove new pkg information
14816             if (newPackage != null) {
14817                 removeInstalledPackageLI(newPackage, true);
14818             }
14819             // Add back the old system package
14820             try {
14821                 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
14822             } catch (PackageManagerException e) {
14823                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
14824             }
14825
14826             synchronized (mPackages) {
14827                 if (disabledSystem) {
14828                     enableSystemPackageLPw(deletedPackage);
14829                 }
14830
14831                 // Ensure the installer package name up to date
14832                 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14833
14834                 // Update permissions for restored package
14835                 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14836
14837                 mSettings.writeLPr();
14838             }
14839
14840             Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
14841                     + " after failed upgrade");
14842         }
14843     }
14844
14845     /**
14846      * Checks whether the parent or any of the child packages have a change shared
14847      * user. For a package to be a valid update the shred users of the parent and
14848      * the children should match. We may later support changing child shared users.
14849      * @param oldPkg The updated package.
14850      * @param newPkg The update package.
14851      * @return The shared user that change between the versions.
14852      */
14853     private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
14854             PackageParser.Package newPkg) {
14855         // Check parent shared user
14856         if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
14857             return newPkg.packageName;
14858         }
14859         // Check child shared users
14860         final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14861         final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
14862         for (int i = 0; i < newChildCount; i++) {
14863             PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
14864             // If this child was present, did it have the same shared user?
14865             for (int j = 0; j < oldChildCount; j++) {
14866                 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
14867                 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
14868                         && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
14869                     return newChildPkg.packageName;
14870                 }
14871             }
14872         }
14873         return null;
14874     }
14875
14876     private void removeNativeBinariesLI(PackageSetting ps) {
14877         // Remove the lib path for the parent package
14878         if (ps != null) {
14879             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
14880             // Remove the lib path for the child packages
14881             final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
14882             for (int i = 0; i < childCount; i++) {
14883                 PackageSetting childPs = null;
14884                 synchronized (mPackages) {
14885                     childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
14886                 }
14887                 if (childPs != null) {
14888                     NativeLibraryHelper.removeNativeBinariesLI(childPs
14889                             .legacyNativeLibraryPathString);
14890                 }
14891             }
14892         }
14893     }
14894
14895     private void enableSystemPackageLPw(PackageParser.Package pkg) {
14896         // Enable the parent package
14897         mSettings.enableSystemPackageLPw(pkg.packageName);
14898         // Enable the child packages
14899         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14900         for (int i = 0; i < childCount; i++) {
14901             PackageParser.Package childPkg = pkg.childPackages.get(i);
14902             mSettings.enableSystemPackageLPw(childPkg.packageName);
14903         }
14904     }
14905
14906     private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
14907             PackageParser.Package newPkg) {
14908         // Disable the parent package (parent always replaced)
14909         boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
14910         // Disable the child packages
14911         final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14912         for (int i = 0; i < childCount; i++) {
14913             PackageParser.Package childPkg = oldPkg.childPackages.get(i);
14914             final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
14915             disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
14916         }
14917         return disabled;
14918     }
14919
14920     private void setInstallerPackageNameLPw(PackageParser.Package pkg,
14921             String installerPackageName) {
14922         // Enable the parent package
14923         mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
14924         // Enable the child packages
14925         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14926         for (int i = 0; i < childCount; i++) {
14927             PackageParser.Package childPkg = pkg.childPackages.get(i);
14928             mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
14929         }
14930     }
14931
14932     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
14933         // Collect all used permissions in the UID
14934         ArraySet<String> usedPermissions = new ArraySet<>();
14935         final int packageCount = su.packages.size();
14936         for (int i = 0; i < packageCount; i++) {
14937             PackageSetting ps = su.packages.valueAt(i);
14938             if (ps.pkg == null) {
14939                 continue;
14940             }
14941             final int requestedPermCount = ps.pkg.requestedPermissions.size();
14942             for (int j = 0; j < requestedPermCount; j++) {
14943                 String permission = ps.pkg.requestedPermissions.get(j);
14944                 BasePermission bp = mSettings.mPermissions.get(permission);
14945                 if (bp != null) {
14946                     usedPermissions.add(permission);
14947                 }
14948             }
14949         }
14950
14951         PermissionsState permissionsState = su.getPermissionsState();
14952         // Prune install permissions
14953         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
14954         final int installPermCount = installPermStates.size();
14955         for (int i = installPermCount - 1; i >= 0;  i--) {
14956             PermissionState permissionState = installPermStates.get(i);
14957             if (!usedPermissions.contains(permissionState.getName())) {
14958                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14959                 if (bp != null) {
14960                     permissionsState.revokeInstallPermission(bp);
14961                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
14962                             PackageManager.MASK_PERMISSION_FLAGS, 0);
14963                 }
14964             }
14965         }
14966
14967         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
14968
14969         // Prune runtime permissions
14970         for (int userId : allUserIds) {
14971             List<PermissionState> runtimePermStates = permissionsState
14972                     .getRuntimePermissionStates(userId);
14973             final int runtimePermCount = runtimePermStates.size();
14974             for (int i = runtimePermCount - 1; i >= 0; i--) {
14975                 PermissionState permissionState = runtimePermStates.get(i);
14976                 if (!usedPermissions.contains(permissionState.getName())) {
14977                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14978                     if (bp != null) {
14979                         permissionsState.revokeRuntimePermission(bp, userId);
14980                         permissionsState.updatePermissionFlags(bp, userId,
14981                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
14982                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
14983                                 runtimePermissionChangedUserIds, userId);
14984                     }
14985                 }
14986             }
14987         }
14988
14989         return runtimePermissionChangedUserIds;
14990     }
14991
14992     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
14993             int[] allUsers, PackageInstalledInfo res, UserHandle user) {
14994         // Update the parent package setting
14995         updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
14996                 res, user);
14997         // Update the child packages setting
14998         final int childCount = (newPackage.childPackages != null)
14999                 ? newPackage.childPackages.size() : 0;
15000         for (int i = 0; i < childCount; i++) {
15001             PackageParser.Package childPackage = newPackage.childPackages.get(i);
15002             PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
15003             updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
15004                     childRes.origUsers, childRes, user);
15005         }
15006     }
15007
15008     private void updateSettingsInternalLI(PackageParser.Package newPackage,
15009             String installerPackageName, int[] allUsers, int[] installedForUsers,
15010             PackageInstalledInfo res, UserHandle user) {
15011         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
15012
15013         String pkgName = newPackage.packageName;
15014         synchronized (mPackages) {
15015             //write settings. the installStatus will be incomplete at this stage.
15016             //note that the new package setting would have already been
15017             //added to mPackages. It hasn't been persisted yet.
15018             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
15019             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
15020             mSettings.writeLPr();
15021             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15022         }
15023
15024         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
15025         synchronized (mPackages) {
15026             updatePermissionsLPw(newPackage.packageName, newPackage,
15027                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
15028                             ? UPDATE_PERMISSIONS_ALL : 0));
15029             // For system-bundled packages, we assume that installing an upgraded version
15030             // of the package implies that the user actually wants to run that new code,
15031             // so we enable the package.
15032             PackageSetting ps = mSettings.mPackages.get(pkgName);
15033             final int userId = user.getIdentifier();
15034             if (ps != null) {
15035                 if (isSystemApp(newPackage)) {
15036                     if (DEBUG_INSTALL) {
15037                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
15038                     }
15039                     // Enable system package for requested users
15040                     if (res.origUsers != null) {
15041                         for (int origUserId : res.origUsers) {
15042                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
15043                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
15044                                         origUserId, installerPackageName);
15045                             }
15046                         }
15047                     }
15048                     // Also convey the prior install/uninstall state
15049                     if (allUsers != null && installedForUsers != null) {
15050                         for (int currentUserId : allUsers) {
15051                             final boolean installed = ArrayUtils.contains(
15052                                     installedForUsers, currentUserId);
15053                             if (DEBUG_INSTALL) {
15054                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
15055                             }
15056                             ps.setInstalled(installed, currentUserId);
15057                         }
15058                         // these install state changes will be persisted in the
15059                         // upcoming call to mSettings.writeLPr().
15060                     }
15061                 }
15062                 // It's implied that when a user requests installation, they want the app to be
15063                 // installed and enabled.
15064                 if (userId != UserHandle.USER_ALL) {
15065                     ps.setInstalled(true, userId);
15066                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
15067                 }
15068             }
15069             res.name = pkgName;
15070             res.uid = newPackage.applicationInfo.uid;
15071             res.pkg = newPackage;
15072             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
15073             mSettings.setInstallerPackageName(pkgName, installerPackageName);
15074             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15075             //to update install status
15076             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
15077             mSettings.writeLPr();
15078             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15079         }
15080
15081         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15082     }
15083
15084     private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
15085         try {
15086             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
15087             installPackageLI(args, res);
15088         } finally {
15089             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15090         }
15091     }
15092
15093     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
15094         final int installFlags = args.installFlags;
15095         final String installerPackageName = args.installerPackageName;
15096         final String volumeUuid = args.volumeUuid;
15097         final File tmpPackageFile = new File(args.getCodePath());
15098         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
15099         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
15100                 || (args.volumeUuid != null));
15101         final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
15102         final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
15103         boolean replace = false;
15104         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
15105         if (args.move != null) {
15106             // moving a complete application; perform an initial scan on the new install location
15107             scanFlags |= SCAN_INITIAL;
15108         }
15109         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
15110             scanFlags |= SCAN_DONT_KILL_APP;
15111         }
15112
15113         // Result object to be returned
15114         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15115
15116         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
15117
15118         // Sanity check
15119         if (ephemeral && (forwardLocked || onExternal)) {
15120             Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
15121                     + " external=" + onExternal);
15122             res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
15123             return;
15124         }
15125
15126         // Retrieve PackageSettings and parse package
15127         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
15128                 | PackageParser.PARSE_ENFORCE_CODE
15129                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
15130                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
15131                 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0)
15132                 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
15133         PackageParser pp = new PackageParser();
15134         pp.setSeparateProcesses(mSeparateProcesses);
15135         pp.setDisplayMetrics(mMetrics);
15136
15137         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
15138         final PackageParser.Package pkg;
15139         try {
15140             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
15141         } catch (PackageParserException e) {
15142             res.setError("Failed parse during installPackageLI", e);
15143             return;
15144         } finally {
15145             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15146         }
15147
15148         // If we are installing a clustered package add results for the children
15149         if (pkg.childPackages != null) {
15150             synchronized (mPackages) {
15151                 final int childCount = pkg.childPackages.size();
15152                 for (int i = 0; i < childCount; i++) {
15153                     PackageParser.Package childPkg = pkg.childPackages.get(i);
15154                     PackageInstalledInfo childRes = new PackageInstalledInfo();
15155                     childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15156                     childRes.pkg = childPkg;
15157                     childRes.name = childPkg.packageName;
15158                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
15159                     if (childPs != null) {
15160                         childRes.origUsers = childPs.queryInstalledUsers(
15161                                 sUserManager.getUserIds(), true);
15162                     }
15163                     if ((mPackages.containsKey(childPkg.packageName))) {
15164                         childRes.removedInfo = new PackageRemovedInfo();
15165                         childRes.removedInfo.removedPackage = childPkg.packageName;
15166                     }
15167                     if (res.addedChildPackages == null) {
15168                         res.addedChildPackages = new ArrayMap<>();
15169                     }
15170                     res.addedChildPackages.put(childPkg.packageName, childRes);
15171                 }
15172             }
15173         }
15174
15175         // If package doesn't declare API override, mark that we have an install
15176         // time CPU ABI override.
15177         if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
15178             pkg.cpuAbiOverride = args.abiOverride;
15179         }
15180
15181         String pkgName = res.name = pkg.packageName;
15182         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
15183             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
15184                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
15185                 return;
15186             }
15187         }
15188
15189         try {
15190             // either use what we've been given or parse directly from the APK
15191             if (args.certificates != null) {
15192                 try {
15193                     PackageParser.populateCertificates(pkg, args.certificates);
15194                 } catch (PackageParserException e) {
15195                     // there was something wrong with the certificates we were given;
15196                     // try to pull them from the APK
15197                     PackageParser.collectCertificates(pkg, parseFlags);
15198                 }
15199             } else {
15200                 PackageParser.collectCertificates(pkg, parseFlags);
15201             }
15202         } catch (PackageParserException e) {
15203             res.setError("Failed collect during installPackageLI", e);
15204             return;
15205         }
15206
15207         // Get rid of all references to package scan path via parser.
15208         pp = null;
15209         String oldCodePath = null;
15210         boolean systemApp = false;
15211         synchronized (mPackages) {
15212             // Check if installing already existing package
15213             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15214                 String oldName = mSettings.mRenamedPackages.get(pkgName);
15215                 if (pkg.mOriginalPackages != null
15216                         && pkg.mOriginalPackages.contains(oldName)
15217                         && mPackages.containsKey(oldName)) {
15218                     // This package is derived from an original package,
15219                     // and this device has been updating from that original
15220                     // name.  We must continue using the original name, so
15221                     // rename the new package here.
15222                     pkg.setPackageName(oldName);
15223                     pkgName = pkg.packageName;
15224                     replace = true;
15225                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
15226                             + oldName + " pkgName=" + pkgName);
15227                 } else if (mPackages.containsKey(pkgName)) {
15228                     // This package, under its official name, already exists
15229                     // on the device; we should replace it.
15230                     replace = true;
15231                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
15232                 }
15233
15234                 // Child packages are installed through the parent package
15235                 if (pkg.parentPackage != null) {
15236                     res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
15237                             "Package " + pkg.packageName + " is child of package "
15238                                     + pkg.parentPackage.parentPackage + ". Child packages "
15239                                     + "can be updated only through the parent package.");
15240                     return;
15241                 }
15242
15243                 if (replace) {
15244                     // Prevent apps opting out from runtime permissions
15245                     PackageParser.Package oldPackage = mPackages.get(pkgName);
15246                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
15247                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
15248                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
15249                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
15250                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
15251                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
15252                                         + " doesn't support runtime permissions but the old"
15253                                         + " target SDK " + oldTargetSdk + " does.");
15254                         return;
15255                     }
15256
15257                     // Prevent installing of child packages
15258                     if (oldPackage.parentPackage != null) {
15259                         res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
15260                                 "Package " + pkg.packageName + " is child of package "
15261                                         + oldPackage.parentPackage + ". Child packages "
15262                                         + "can be updated only through the parent package.");
15263                         return;
15264                     }
15265                 }
15266             }
15267
15268             PackageSetting ps = mSettings.mPackages.get(pkgName);
15269             if (ps != null) {
15270                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
15271
15272                 // Quick sanity check that we're signed correctly if updating;
15273                 // we'll check this again later when scanning, but we want to
15274                 // bail early here before tripping over redefined permissions.
15275                 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
15276                     if (!checkUpgradeKeySetLP(ps, pkg)) {
15277                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
15278                                 + pkg.packageName + " upgrade keys do not match the "
15279                                 + "previously installed version");
15280                         return;
15281                     }
15282                 } else {
15283                     try {
15284                         verifySignaturesLP(ps, pkg);
15285                     } catch (PackageManagerException e) {
15286                         res.setError(e.error, e.getMessage());
15287                         return;
15288                     }
15289                 }
15290
15291                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
15292                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
15293                     systemApp = (ps.pkg.applicationInfo.flags &
15294                             ApplicationInfo.FLAG_SYSTEM) != 0;
15295                 }
15296                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
15297             }
15298
15299             // Check whether the newly-scanned package wants to define an already-defined perm
15300             int N = pkg.permissions.size();
15301             for (int i = N-1; i >= 0; i--) {
15302                 PackageParser.Permission perm = pkg.permissions.get(i);
15303                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
15304                 if (bp != null) {
15305                     // If the defining package is signed with our cert, it's okay.  This
15306                     // also includes the "updating the same package" case, of course.
15307                     // "updating same package" could also involve key-rotation.
15308                     final boolean sigsOk;
15309                     if (bp.sourcePackage.equals(pkg.packageName)
15310                             && (bp.packageSetting instanceof PackageSetting)
15311                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
15312                                     scanFlags))) {
15313                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
15314                     } else {
15315                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
15316                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
15317                     }
15318                     if (!sigsOk) {
15319                         // If the owning package is the system itself, we log but allow
15320                         // install to proceed; we fail the install on all other permission
15321                         // redefinitions.
15322                         if (!bp.sourcePackage.equals("android")) {
15323                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
15324                                     + pkg.packageName + " attempting to redeclare permission "
15325                                     + perm.info.name + " already owned by " + bp.sourcePackage);
15326                             res.origPermission = perm.info.name;
15327                             res.origPackage = bp.sourcePackage;
15328                             return;
15329                         } else {
15330                             Slog.w(TAG, "Package " + pkg.packageName
15331                                     + " attempting to redeclare system permission "
15332                                     + perm.info.name + "; ignoring new declaration");
15333                             pkg.permissions.remove(i);
15334                         }
15335                     } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
15336                         // Prevent apps to change protection level to dangerous from any other
15337                         // type as this would allow a privilege escalation where an app adds a
15338                         // normal/signature permission in other app's group and later redefines
15339                         // it as dangerous leading to the group auto-grant.
15340                         if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
15341                                 == PermissionInfo.PROTECTION_DANGEROUS) {
15342                             if (bp != null && !bp.isRuntime()) {
15343                                 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
15344                                         + "non-runtime permission " + perm.info.name
15345                                         + " to runtime; keeping old protection level");
15346                                 perm.info.protectionLevel = bp.protectionLevel;
15347                             }
15348                         }
15349                     }
15350                 }
15351             }
15352         }
15353
15354         if (systemApp) {
15355             if (onExternal) {
15356                 // Abort update; system app can't be replaced with app on sdcard
15357                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
15358                         "Cannot install updates to system apps on sdcard");
15359                 return;
15360             } else if (ephemeral) {
15361                 // Abort update; system app can't be replaced with an ephemeral app
15362                 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
15363                         "Cannot update a system app with an ephemeral app");
15364                 return;
15365             }
15366         }
15367
15368         if (args.move != null) {
15369             // We did an in-place move, so dex is ready to roll
15370             scanFlags |= SCAN_NO_DEX;
15371             scanFlags |= SCAN_MOVE;
15372
15373             synchronized (mPackages) {
15374                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
15375                 if (ps == null) {
15376                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
15377                             "Missing settings for moved package " + pkgName);
15378                 }
15379
15380                 // We moved the entire application as-is, so bring over the
15381                 // previously derived ABI information.
15382                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
15383                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
15384             }
15385
15386         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
15387             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
15388             scanFlags |= SCAN_NO_DEX;
15389
15390             try {
15391                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
15392                     args.abiOverride : pkg.cpuAbiOverride);
15393                 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
15394                         true /* extract libs */);
15395             } catch (PackageManagerException pme) {
15396                 Slog.e(TAG, "Error deriving application ABI", pme);
15397                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
15398                 return;
15399             }
15400
15401             // Shared libraries for the package need to be updated.
15402             synchronized (mPackages) {
15403                 try {
15404                     updateSharedLibrariesLPw(pkg, null);
15405                 } catch (PackageManagerException e) {
15406                     Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage());
15407                 }
15408             }
15409             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
15410             // Do not run PackageDexOptimizer through the local performDexOpt
15411             // method because `pkg` may not be in `mPackages` yet.
15412             //
15413             // Also, don't fail application installs if the dexopt step fails.
15414             mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
15415                     null /* instructionSets */, false /* checkProfiles */,
15416                     getCompilerFilterForReason(REASON_INSTALL),
15417                     getOrCreateCompilerPackageStats(pkg));
15418             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15419
15420             // Notify BackgroundDexOptService that the package has been changed.
15421             // If this is an update of a package which used to fail to compile,
15422             // BDOS will remove it from its blacklist.
15423             BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
15424         }
15425
15426         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
15427             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
15428             return;
15429         }
15430
15431         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
15432
15433         try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
15434                 "installPackageLI")) {
15435             if (replace) {
15436                 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
15437                         installerPackageName, res);
15438             } else {
15439                 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
15440                         args.user, installerPackageName, volumeUuid, res);
15441             }
15442         }
15443         synchronized (mPackages) {
15444             final PackageSetting ps = mSettings.mPackages.get(pkgName);
15445             if (ps != null) {
15446                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
15447             }
15448
15449             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15450             for (int i = 0; i < childCount; i++) {
15451                 PackageParser.Package childPkg = pkg.childPackages.get(i);
15452                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15453                 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
15454                 if (childPs != null) {
15455                     childRes.newUsers = childPs.queryInstalledUsers(
15456                             sUserManager.getUserIds(), true);
15457                 }
15458             }
15459         }
15460     }
15461
15462     private void startIntentFilterVerifications(int userId, boolean replacing,
15463             PackageParser.Package pkg) {
15464         if (mIntentFilterVerifierComponent == null) {
15465             Slog.w(TAG, "No IntentFilter verification will not be done as "
15466                     + "there is no IntentFilterVerifier available!");
15467             return;
15468         }
15469
15470         final int verifierUid = getPackageUid(
15471                 mIntentFilterVerifierComponent.getPackageName(),
15472                 MATCH_DEBUG_TRIAGED_MISSING,
15473                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
15474
15475         Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15476         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
15477         mHandler.sendMessage(msg);
15478
15479         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15480         for (int i = 0; i < childCount; i++) {
15481             PackageParser.Package childPkg = pkg.childPackages.get(i);
15482             msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15483             msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
15484             mHandler.sendMessage(msg);
15485         }
15486     }
15487
15488     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
15489             PackageParser.Package pkg) {
15490         int size = pkg.activities.size();
15491         if (size == 0) {
15492             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15493                     "No activity, so no need to verify any IntentFilter!");
15494             return;
15495         }
15496
15497         final boolean hasDomainURLs = hasDomainURLs(pkg);
15498         if (!hasDomainURLs) {
15499             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15500                     "No domain URLs, so no need to verify any IntentFilter!");
15501             return;
15502         }
15503
15504         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
15505                 + " if any IntentFilter from the " + size
15506                 + " Activities needs verification ...");
15507
15508         int count = 0;
15509         final String packageName = pkg.packageName;
15510
15511         synchronized (mPackages) {
15512             // If this is a new install and we see that we've already run verification for this
15513             // package, we have nothing to do: it means the state was restored from backup.
15514             if (!replacing) {
15515                 IntentFilterVerificationInfo ivi =
15516                         mSettings.getIntentFilterVerificationLPr(packageName);
15517                 if (ivi != null) {
15518                     if (DEBUG_DOMAIN_VERIFICATION) {
15519                         Slog.i(TAG, "Package " + packageName+ " already verified: status="
15520                                 + ivi.getStatusString());
15521                     }
15522                     return;
15523                 }
15524             }
15525
15526             // If any filters need to be verified, then all need to be.
15527             boolean needToVerify = false;
15528             for (PackageParser.Activity a : pkg.activities) {
15529                 for (ActivityIntentInfo filter : a.intents) {
15530                     if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
15531                         if (DEBUG_DOMAIN_VERIFICATION) {
15532                             Slog.d(TAG, "Intent filter needs verification, so processing all filters");
15533                         }
15534                         needToVerify = true;
15535                         break;
15536                     }
15537                 }
15538             }
15539
15540             if (needToVerify) {
15541                 final int verificationId = mIntentFilterVerificationToken++;
15542                 for (PackageParser.Activity a : pkg.activities) {
15543                     for (ActivityIntentInfo filter : a.intents) {
15544                         if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
15545                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15546                                     "Verification needed for IntentFilter:" + filter.toString());
15547                             mIntentFilterVerifier.addOneIntentFilterVerification(
15548                                     verifierUid, userId, verificationId, filter, packageName);
15549                             count++;
15550                         }
15551                     }
15552                 }
15553             }
15554         }
15555
15556         if (count > 0) {
15557             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
15558                     + " IntentFilter verification" + (count > 1 ? "s" : "")
15559                     +  " for userId:" + userId);
15560             mIntentFilterVerifier.startVerifications(userId);
15561         } else {
15562             if (DEBUG_DOMAIN_VERIFICATION) {
15563                 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
15564             }
15565         }
15566     }
15567
15568     private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
15569         final ComponentName cn  = filter.activity.getComponentName();
15570         final String packageName = cn.getPackageName();
15571
15572         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
15573                 packageName);
15574         if (ivi == null) {
15575             return true;
15576         }
15577         int status = ivi.getStatus();
15578         switch (status) {
15579             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
15580             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
15581                 return true;
15582
15583             default:
15584                 // Nothing to do
15585                 return false;
15586         }
15587     }
15588
15589     private static boolean isMultiArch(ApplicationInfo info) {
15590         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
15591     }
15592
15593     private static boolean isExternal(PackageParser.Package pkg) {
15594         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15595     }
15596
15597     private static boolean isExternal(PackageSetting ps) {
15598         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15599     }
15600
15601     private static boolean isEphemeral(PackageParser.Package pkg) {
15602         return pkg.applicationInfo.isEphemeralApp();
15603     }
15604
15605     private static boolean isEphemeral(PackageSetting ps) {
15606         return ps.pkg != null && isEphemeral(ps.pkg);
15607     }
15608
15609     private static boolean isSystemApp(PackageParser.Package pkg) {
15610         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
15611     }
15612
15613     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
15614         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15615     }
15616
15617     private static boolean hasDomainURLs(PackageParser.Package pkg) {
15618         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
15619     }
15620
15621     private static boolean isSystemApp(PackageSetting ps) {
15622         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
15623     }
15624
15625     private static boolean isUpdatedSystemApp(PackageSetting ps) {
15626         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
15627     }
15628
15629     private int packageFlagsToInstallFlags(PackageSetting ps) {
15630         int installFlags = 0;
15631         if (isEphemeral(ps)) {
15632             installFlags |= PackageManager.INSTALL_EPHEMERAL;
15633         }
15634         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
15635             // This existing package was an external ASEC install when we have
15636             // the external flag without a UUID
15637             installFlags |= PackageManager.INSTALL_EXTERNAL;
15638         }
15639         if (ps.isForwardLocked()) {
15640             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
15641         }
15642         return installFlags;
15643     }
15644
15645     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
15646         if (isExternal(pkg)) {
15647             if (TextUtils.isEmpty(pkg.volumeUuid)) {
15648                 return StorageManager.UUID_PRIMARY_PHYSICAL;
15649             } else {
15650                 return pkg.volumeUuid;
15651             }
15652         } else {
15653             return StorageManager.UUID_PRIVATE_INTERNAL;
15654         }
15655     }
15656
15657     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
15658         if (isExternal(pkg)) {
15659             if (TextUtils.isEmpty(pkg.volumeUuid)) {
15660                 return mSettings.getExternalVersion();
15661             } else {
15662                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
15663             }
15664         } else {
15665             return mSettings.getInternalVersion();
15666         }
15667     }
15668
15669     private void deleteTempPackageFiles() {
15670         final FilenameFilter filter = new FilenameFilter() {
15671             public boolean accept(File dir, String name) {
15672                 return name.startsWith("vmdl") && name.endsWith(".tmp");
15673             }
15674         };
15675         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
15676             file.delete();
15677         }
15678     }
15679
15680     @Override
15681     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
15682             int flags) {
15683         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
15684                 flags);
15685     }
15686
15687     @Override
15688     public void deletePackage(final String packageName,
15689             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
15690         mContext.enforceCallingOrSelfPermission(
15691                 android.Manifest.permission.DELETE_PACKAGES, null);
15692         Preconditions.checkNotNull(packageName);
15693         Preconditions.checkNotNull(observer);
15694         final int uid = Binder.getCallingUid();
15695         if (!isOrphaned(packageName)
15696                 && !isCallerAllowedToSilentlyUninstall(uid, packageName)) {
15697             try {
15698                 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
15699                 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
15700                 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
15701                 observer.onUserActionRequired(intent);
15702             } catch (RemoteException re) {
15703             }
15704             return;
15705         }
15706         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
15707         final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
15708         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
15709             mContext.enforceCallingOrSelfPermission(
15710                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15711                     "deletePackage for user " + userId);
15712         }
15713
15714         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
15715             try {
15716                 observer.onPackageDeleted(packageName,
15717                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
15718             } catch (RemoteException re) {
15719             }
15720             return;
15721         }
15722
15723         if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) {
15724             try {
15725                 observer.onPackageDeleted(packageName,
15726                         PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
15727             } catch (RemoteException re) {
15728             }
15729             return;
15730         }
15731
15732         if (DEBUG_REMOVE) {
15733             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId
15734                     + " deleteAllUsers: " + deleteAllUsers );
15735         }
15736         // Queue up an async operation since the package deletion may take a little while.
15737         mHandler.post(new Runnable() {
15738             public void run() {
15739                 mHandler.removeCallbacks(this);
15740                 int returnCode;
15741                 if (!deleteAllUsers) {
15742                     returnCode = deletePackageX(packageName, userId, deleteFlags);
15743                 } else {
15744                     int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users);
15745                     // If nobody is blocking uninstall, proceed with delete for all users
15746                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
15747                         returnCode = deletePackageX(packageName, userId, deleteFlags);
15748                     } else {
15749                         // Otherwise uninstall individually for users with blockUninstalls=false
15750                         final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
15751                         for (int userId : users) {
15752                             if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
15753                                 returnCode = deletePackageX(packageName, userId, userFlags);
15754                                 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
15755                                     Slog.w(TAG, "Package delete failed for user " + userId
15756                                             + ", returnCode " + returnCode);
15757                                 }
15758                             }
15759                         }
15760                         // The app has only been marked uninstalled for certain users.
15761                         // We still need to report that delete was blocked
15762                         returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
15763                     }
15764                 }
15765                 try {
15766                     observer.onPackageDeleted(packageName, returnCode, null);
15767                 } catch (RemoteException e) {
15768                     Log.i(TAG, "Observer no longer exists.");
15769                 } //end catch
15770             } //end run
15771         });
15772     }
15773
15774     private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
15775         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
15776               || callingUid == Process.SYSTEM_UID) {
15777             return true;
15778         }
15779         final int callingUserId = UserHandle.getUserId(callingUid);
15780         // If the caller installed the pkgName, then allow it to silently uninstall.
15781         if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
15782             return true;
15783         }
15784
15785         // Allow package verifier to silently uninstall.
15786         if (mRequiredVerifierPackage != null &&
15787                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
15788             return true;
15789         }
15790
15791         // Allow package uninstaller to silently uninstall.
15792         if (mRequiredUninstallerPackage != null &&
15793                 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
15794             return true;
15795         }
15796
15797         // Allow storage manager to silently uninstall.
15798         if (mStorageManagerPackage != null &&
15799                 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
15800             return true;
15801         }
15802         return false;
15803     }
15804
15805     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
15806         int[] result = EMPTY_INT_ARRAY;
15807         for (int userId : userIds) {
15808             if (getBlockUninstallForUser(packageName, userId)) {
15809                 result = ArrayUtils.appendInt(result, userId);
15810             }
15811         }
15812         return result;
15813     }
15814
15815     @Override
15816     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
15817         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
15818     }
15819
15820     private boolean isPackageDeviceAdmin(String packageName, int userId) {
15821         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
15822                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
15823         try {
15824             if (dpm != null) {
15825                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
15826                         /* callingUserOnly =*/ false);
15827                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
15828                         : deviceOwnerComponentName.getPackageName();
15829                 // Does the package contains the device owner?
15830                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
15831                 // this check is probably not needed, since DO should be registered as a device
15832                 // admin on some user too. (Original bug for this: b/17657954)
15833                 if (packageName.equals(deviceOwnerPackageName)) {
15834                     return true;
15835                 }
15836                 // Does it contain a device admin for any user?
15837                 int[] users;
15838                 if (userId == UserHandle.USER_ALL) {
15839                     users = sUserManager.getUserIds();
15840                 } else {
15841                     users = new int[]{userId};
15842                 }
15843                 for (int i = 0; i < users.length; ++i) {
15844                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
15845                         return true;
15846                     }
15847                 }
15848             }
15849         } catch (RemoteException e) {
15850         }
15851         return false;
15852     }
15853
15854     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
15855         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
15856     }
15857
15858     /**
15859      *  This method is an internal method that could be get invoked either
15860      *  to delete an installed package or to clean up a failed installation.
15861      *  After deleting an installed package, a broadcast is sent to notify any
15862      *  listeners that the package has been removed. For cleaning up a failed
15863      *  installation, the broadcast is not necessary since the package's
15864      *  installation wouldn't have sent the initial broadcast either
15865      *  The key steps in deleting a package are
15866      *  deleting the package information in internal structures like mPackages,
15867      *  deleting the packages base directories through installd
15868      *  updating mSettings to reflect current status
15869      *  persisting settings for later use
15870      *  sending a broadcast if necessary
15871      */
15872     private int deletePackageX(String packageName, int userId, int deleteFlags) {
15873         final PackageRemovedInfo info = new PackageRemovedInfo();
15874         final boolean res;
15875
15876         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
15877                 ? UserHandle.USER_ALL : userId;
15878
15879         if (isPackageDeviceAdmin(packageName, removeUser)) {
15880             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
15881             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
15882         }
15883
15884         PackageSetting uninstalledPs = null;
15885
15886         // for the uninstall-updates case and restricted profiles, remember the per-
15887         // user handle installed state
15888         int[] allUsers;
15889         synchronized (mPackages) {
15890             uninstalledPs = mSettings.mPackages.get(packageName);
15891             if (uninstalledPs == null) {
15892                 Slog.w(TAG, "Not removing non-existent package " + packageName);
15893                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15894             }
15895             allUsers = sUserManager.getUserIds();
15896             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
15897         }
15898
15899         final int freezeUser;
15900         if (isUpdatedSystemApp(uninstalledPs)
15901                 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
15902             // We're downgrading a system app, which will apply to all users, so
15903             // freeze them all during the downgrade
15904             freezeUser = UserHandle.USER_ALL;
15905         } else {
15906             freezeUser = removeUser;
15907         }
15908
15909         synchronized (mInstallLock) {
15910             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
15911             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
15912                     deleteFlags, "deletePackageX")) {
15913                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
15914                         deleteFlags | REMOVE_CHATTY, info, true, null);
15915             }
15916             synchronized (mPackages) {
15917                 if (res) {
15918                     mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
15919                 }
15920             }
15921         }
15922
15923         if (res) {
15924             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
15925             info.sendPackageRemovedBroadcasts(killApp);
15926             info.sendSystemPackageUpdatedBroadcasts();
15927             info.sendSystemPackageAppearedBroadcasts();
15928         }
15929         // Force a gc here.
15930         Runtime.getRuntime().gc();
15931         // Delete the resources here after sending the broadcast to let
15932         // other processes clean up before deleting resources.
15933         if (info.args != null) {
15934             synchronized (mInstallLock) {
15935                 info.args.doPostDeleteLI(true);
15936             }
15937         }
15938
15939         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15940     }
15941
15942     class PackageRemovedInfo {
15943         String removedPackage;
15944         int uid = -1;
15945         int removedAppId = -1;
15946         int[] origUsers;
15947         int[] removedUsers = null;
15948         boolean isRemovedPackageSystemUpdate = false;
15949         boolean isUpdate;
15950         boolean dataRemoved;
15951         boolean removedForAllUsers;
15952         // Clean up resources deleted packages.
15953         InstallArgs args = null;
15954         ArrayMap<String, PackageRemovedInfo> removedChildPackages;
15955         ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
15956
15957         void sendPackageRemovedBroadcasts(boolean killApp) {
15958             sendPackageRemovedBroadcastInternal(killApp);
15959             final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
15960             for (int i = 0; i < childCount; i++) {
15961                 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15962                 childInfo.sendPackageRemovedBroadcastInternal(killApp);
15963             }
15964         }
15965
15966         void sendSystemPackageUpdatedBroadcasts() {
15967             if (isRemovedPackageSystemUpdate) {
15968                 sendSystemPackageUpdatedBroadcastsInternal();
15969                 final int childCount = (removedChildPackages != null)
15970                         ? removedChildPackages.size() : 0;
15971                 for (int i = 0; i < childCount; i++) {
15972                     PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15973                     if (childInfo.isRemovedPackageSystemUpdate) {
15974                         childInfo.sendSystemPackageUpdatedBroadcastsInternal();
15975                     }
15976                 }
15977             }
15978         }
15979
15980         void sendSystemPackageAppearedBroadcasts() {
15981             final int packageCount = (appearedChildPackages != null)
15982                     ? appearedChildPackages.size() : 0;
15983             for (int i = 0; i < packageCount; i++) {
15984                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
15985                 for (int userId : installedInfo.newUsers) {
15986                     sendPackageAddedForUser(installedInfo.name, true,
15987                             UserHandle.getAppId(installedInfo.uid), userId);
15988                 }
15989             }
15990         }
15991
15992         private void sendSystemPackageUpdatedBroadcastsInternal() {
15993             Bundle extras = new Bundle(2);
15994             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
15995             extras.putBoolean(Intent.EXTRA_REPLACING, true);
15996             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
15997                     extras, 0, null, null, null);
15998             sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
15999                     extras, 0, null, null, null);
16000             sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
16001                     null, 0, removedPackage, null, null);
16002         }
16003
16004         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
16005             Bundle extras = new Bundle(2);
16006             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
16007             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
16008             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
16009             if (isUpdate || isRemovedPackageSystemUpdate) {
16010                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
16011             }
16012             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
16013             if (removedPackage != null) {
16014                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
16015                         extras, 0, null, null, removedUsers);
16016                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
16017                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
16018                             removedPackage, extras, 0, null, null, removedUsers);
16019                 }
16020             }
16021             if (removedAppId >= 0) {
16022                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
16023                         removedUsers);
16024             }
16025         }
16026     }
16027
16028     /*
16029      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
16030      * flag is not set, the data directory is removed as well.
16031      * make sure this flag is set for partially installed apps. If not its meaningless to
16032      * delete a partially installed application.
16033      */
16034     private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
16035             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
16036         String packageName = ps.name;
16037         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
16038         // Retrieve object to delete permissions for shared user later on
16039         final PackageParser.Package deletedPkg;
16040         final PackageSetting deletedPs;
16041         // reader
16042         synchronized (mPackages) {
16043             deletedPkg = mPackages.get(packageName);
16044             deletedPs = mSettings.mPackages.get(packageName);
16045             if (outInfo != null) {
16046                 outInfo.removedPackage = packageName;
16047                 outInfo.removedUsers = deletedPs != null
16048                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
16049                         : null;
16050             }
16051         }
16052
16053         removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
16054
16055         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
16056             final PackageParser.Package resolvedPkg;
16057             if (deletedPkg != null) {
16058                 resolvedPkg = deletedPkg;
16059             } else {
16060                 // We don't have a parsed package when it lives on an ejected
16061                 // adopted storage device, so fake something together
16062                 resolvedPkg = new PackageParser.Package(ps.name);
16063                 resolvedPkg.setVolumeUuid(ps.volumeUuid);
16064             }
16065             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
16066                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16067             destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
16068             if (outInfo != null) {
16069                 outInfo.dataRemoved = true;
16070             }
16071             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
16072         }
16073
16074         // writer
16075         synchronized (mPackages) {
16076             if (deletedPs != null) {
16077                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
16078                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
16079                     clearDefaultBrowserIfNeeded(packageName);
16080                     if (outInfo != null) {
16081                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
16082                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
16083                     }
16084                     updatePermissionsLPw(deletedPs.name, null, 0);
16085                     if (deletedPs.sharedUser != null) {
16086                         // Remove permissions associated with package. Since runtime
16087                         // permissions are per user we have to kill the removed package
16088                         // or packages running under the shared user of the removed
16089                         // package if revoking the permissions requested only by the removed
16090                         // package is successful and this causes a change in gids.
16091                         for (int userId : UserManagerService.getInstance().getUserIds()) {
16092                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
16093                                     userId);
16094                             if (userIdToKill == UserHandle.USER_ALL
16095                                     || userIdToKill >= UserHandle.USER_SYSTEM) {
16096                                 // If gids changed for this user, kill all affected packages.
16097                                 mHandler.post(new Runnable() {
16098                                     @Override
16099                                     public void run() {
16100                                         // This has to happen with no lock held.
16101                                         killApplication(deletedPs.name, deletedPs.appId,
16102                                                 KILL_APP_REASON_GIDS_CHANGED);
16103                                     }
16104                                 });
16105                                 break;
16106                             }
16107                         }
16108                     }
16109                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
16110                 }
16111                 // make sure to preserve per-user disabled state if this removal was just
16112                 // a downgrade of a system app to the factory package
16113                 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
16114                     if (DEBUG_REMOVE) {
16115                         Slog.d(TAG, "Propagating install state across downgrade");
16116                     }
16117                     for (int userId : allUserHandles) {
16118                         final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
16119                         if (DEBUG_REMOVE) {
16120                             Slog.d(TAG, "    user " + userId + " => " + installed);
16121                         }
16122                         ps.setInstalled(installed, userId);
16123                     }
16124                 }
16125             }
16126             // can downgrade to reader
16127             if (writeSettings) {
16128                 // Save settings now
16129                 mSettings.writeLPr();
16130             }
16131         }
16132         if (outInfo != null) {
16133             // A user ID was deleted here. Go through all users and remove it
16134             // from KeyStore.
16135             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
16136         }
16137     }
16138
16139     static boolean locationIsPrivileged(File path) {
16140         try {
16141             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
16142                     .getCanonicalPath();
16143             return path.getCanonicalPath().startsWith(privilegedAppDir);
16144         } catch (IOException e) {
16145             Slog.e(TAG, "Unable to access code path " + path);
16146         }
16147         return false;
16148     }
16149
16150     /*
16151      * Tries to delete system package.
16152      */
16153     private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
16154             PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
16155             boolean writeSettings) {
16156         if (deletedPs.parentPackageName != null) {
16157             Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
16158             return false;
16159         }
16160
16161         final boolean applyUserRestrictions
16162                 = (allUserHandles != null) && (outInfo.origUsers != null);
16163         final PackageSetting disabledPs;
16164         // Confirm if the system package has been updated
16165         // An updated system app can be deleted. This will also have to restore
16166         // the system pkg from system partition
16167         // reader
16168         synchronized (mPackages) {
16169             disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
16170         }
16171
16172         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
16173                 + " disabledPs=" + disabledPs);
16174
16175         if (disabledPs == null) {
16176             Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
16177             return false;
16178         } else if (DEBUG_REMOVE) {
16179             Slog.d(TAG, "Deleting system pkg from data partition");
16180         }
16181
16182         if (DEBUG_REMOVE) {
16183             if (applyUserRestrictions) {
16184                 Slog.d(TAG, "Remembering install states:");
16185                 for (int userId : allUserHandles) {
16186                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
16187                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
16188                 }
16189             }
16190         }
16191
16192         // Delete the updated package
16193         outInfo.isRemovedPackageSystemUpdate = true;
16194         if (outInfo.removedChildPackages != null) {
16195             final int childCount = (deletedPs.childPackageNames != null)
16196                     ? deletedPs.childPackageNames.size() : 0;
16197             for (int i = 0; i < childCount; i++) {
16198                 String childPackageName = deletedPs.childPackageNames.get(i);
16199                 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
16200                         .contains(childPackageName)) {
16201                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
16202                             childPackageName);
16203                     if (childInfo != null) {
16204                         childInfo.isRemovedPackageSystemUpdate = true;
16205                     }
16206                 }
16207             }
16208         }
16209
16210         if (disabledPs.versionCode < deletedPs.versionCode) {
16211             // Delete data for downgrades
16212             flags &= ~PackageManager.DELETE_KEEP_DATA;
16213         } else {
16214             // Preserve data by setting flag
16215             flags |= PackageManager.DELETE_KEEP_DATA;
16216         }
16217
16218         boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
16219                 outInfo, writeSettings, disabledPs.pkg);
16220         if (!ret) {
16221             return false;
16222         }
16223
16224         // writer
16225         synchronized (mPackages) {
16226             // Reinstate the old system package
16227             enableSystemPackageLPw(disabledPs.pkg);
16228             // Remove any native libraries from the upgraded package.
16229             removeNativeBinariesLI(deletedPs);
16230         }
16231
16232         // Install the system package
16233         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
16234         int parseFlags = mDefParseFlags
16235                 | PackageParser.PARSE_MUST_BE_APK
16236                 | PackageParser.PARSE_IS_SYSTEM
16237                 | PackageParser.PARSE_IS_SYSTEM_DIR;
16238         if (locationIsPrivileged(disabledPs.codePath)) {
16239             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
16240         }
16241
16242         final PackageParser.Package newPkg;
16243         try {
16244             newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
16245         } catch (PackageManagerException e) {
16246             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
16247                     + e.getMessage());
16248             return false;
16249         }
16250         try {
16251             // update shared libraries for the newly re-installed system package
16252             updateSharedLibrariesLPw(newPkg, null);
16253         } catch (PackageManagerException e) {
16254             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
16255         }
16256
16257         prepareAppDataAfterInstallLIF(newPkg);
16258
16259         // writer
16260         synchronized (mPackages) {
16261             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
16262
16263             // Propagate the permissions state as we do not want to drop on the floor
16264             // runtime permissions. The update permissions method below will take
16265             // care of removing obsolete permissions and grant install permissions.
16266             ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
16267             updatePermissionsLPw(newPkg.packageName, newPkg,
16268                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
16269
16270             if (applyUserRestrictions) {
16271                 if (DEBUG_REMOVE) {
16272                     Slog.d(TAG, "Propagating install state across reinstall");
16273                 }
16274                 for (int userId : allUserHandles) {
16275                     final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
16276                     if (DEBUG_REMOVE) {
16277                         Slog.d(TAG, "    user " + userId + " => " + installed);
16278                     }
16279                     ps.setInstalled(installed, userId);
16280
16281                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
16282                 }
16283                 // Regardless of writeSettings we need to ensure that this restriction
16284                 // state propagation is persisted
16285                 mSettings.writeAllUsersPackageRestrictionsLPr();
16286             }
16287             // can downgrade to reader here
16288             if (writeSettings) {
16289                 mSettings.writeLPr();
16290             }
16291         }
16292         return true;
16293     }
16294
16295     private boolean deleteInstalledPackageLIF(PackageSetting ps,
16296             boolean deleteCodeAndResources, int flags, int[] allUserHandles,
16297             PackageRemovedInfo outInfo, boolean writeSettings,
16298             PackageParser.Package replacingPackage) {
16299         synchronized (mPackages) {
16300             if (outInfo != null) {
16301                 outInfo.uid = ps.appId;
16302             }
16303
16304             if (outInfo != null && outInfo.removedChildPackages != null) {
16305                 final int childCount = (ps.childPackageNames != null)
16306                         ? ps.childPackageNames.size() : 0;
16307                 for (int i = 0; i < childCount; i++) {
16308                     String childPackageName = ps.childPackageNames.get(i);
16309                     PackageSetting childPs = mSettings.mPackages.get(childPackageName);
16310                     if (childPs == null) {
16311                         return false;
16312                     }
16313                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
16314                             childPackageName);
16315                     if (childInfo != null) {
16316                         childInfo.uid = childPs.appId;
16317                     }
16318                 }
16319             }
16320         }
16321
16322         // Delete package data from internal structures and also remove data if flag is set
16323         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
16324
16325         // Delete the child packages data
16326         final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16327         for (int i = 0; i < childCount; i++) {
16328             PackageSetting childPs;
16329             synchronized (mPackages) {
16330                 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
16331             }
16332             if (childPs != null) {
16333                 PackageRemovedInfo childOutInfo = (outInfo != null
16334                         && outInfo.removedChildPackages != null)
16335                         ? outInfo.removedChildPackages.get(childPs.name) : null;
16336                 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
16337                         && (replacingPackage != null
16338                         && !replacingPackage.hasChildPackage(childPs.name))
16339                         ? flags & ~DELETE_KEEP_DATA : flags;
16340                 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
16341                         deleteFlags, writeSettings);
16342             }
16343         }
16344
16345         // Delete application code and resources only for parent packages
16346         if (ps.parentPackageName == null) {
16347             if (deleteCodeAndResources && (outInfo != null)) {
16348                 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
16349                         ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
16350                 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
16351             }
16352         }
16353
16354         return true;
16355     }
16356
16357     @Override
16358     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
16359             int userId) {
16360         mContext.enforceCallingOrSelfPermission(
16361                 android.Manifest.permission.DELETE_PACKAGES, null);
16362         synchronized (mPackages) {
16363             PackageSetting ps = mSettings.mPackages.get(packageName);
16364             if (ps == null) {
16365                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
16366                 return false;
16367             }
16368             if (!ps.getInstalled(userId)) {
16369                 // Can't block uninstall for an app that is not installed or enabled.
16370                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
16371                 return false;
16372             }
16373             ps.setBlockUninstall(blockUninstall, userId);
16374             mSettings.writePackageRestrictionsLPr(userId);
16375         }
16376         return true;
16377     }
16378
16379     @Override
16380     public boolean getBlockUninstallForUser(String packageName, int userId) {
16381         synchronized (mPackages) {
16382             PackageSetting ps = mSettings.mPackages.get(packageName);
16383             if (ps == null) {
16384                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
16385                 return false;
16386             }
16387             return ps.getBlockUninstall(userId);
16388         }
16389     }
16390
16391     @Override
16392     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
16393         int callingUid = Binder.getCallingUid();
16394         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
16395             throw new SecurityException(
16396                     "setRequiredForSystemUser can only be run by the system or root");
16397         }
16398         synchronized (mPackages) {
16399             PackageSetting ps = mSettings.mPackages.get(packageName);
16400             if (ps == null) {
16401                 Log.w(TAG, "Package doesn't exist: " + packageName);
16402                 return false;
16403             }
16404             if (systemUserApp) {
16405                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
16406             } else {
16407                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
16408             }
16409             mSettings.writeLPr();
16410         }
16411         return true;
16412     }
16413
16414     /*
16415      * This method handles package deletion in general
16416      */
16417     private boolean deletePackageLIF(String packageName, UserHandle user,
16418             boolean deleteCodeAndResources, int[] allUserHandles, int flags,
16419             PackageRemovedInfo outInfo, boolean writeSettings,
16420             PackageParser.Package replacingPackage) {
16421         if (packageName == null) {
16422             Slog.w(TAG, "Attempt to delete null packageName.");
16423             return false;
16424         }
16425
16426         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
16427
16428         PackageSetting ps;
16429
16430         synchronized (mPackages) {
16431             ps = mSettings.mPackages.get(packageName);
16432             if (ps == null) {
16433                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16434                 return false;
16435             }
16436
16437             if (ps.parentPackageName != null && (!isSystemApp(ps)
16438                     || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
16439                 if (DEBUG_REMOVE) {
16440                     Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
16441                             + ((user == null) ? UserHandle.USER_ALL : user));
16442                 }
16443                 final int removedUserId = (user != null) ? user.getIdentifier()
16444                         : UserHandle.USER_ALL;
16445                 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
16446                     return false;
16447                 }
16448                 markPackageUninstalledForUserLPw(ps, user);
16449                 scheduleWritePackageRestrictionsLocked(user);
16450                 return true;
16451             }
16452         }
16453
16454         if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
16455                 && user.getIdentifier() != UserHandle.USER_ALL)) {
16456             // The caller is asking that the package only be deleted for a single
16457             // user.  To do this, we just mark its uninstalled state and delete
16458             // its data. If this is a system app, we only allow this to happen if
16459             // they have set the special DELETE_SYSTEM_APP which requests different
16460             // semantics than normal for uninstalling system apps.
16461             markPackageUninstalledForUserLPw(ps, user);
16462
16463             if (!isSystemApp(ps)) {
16464                 // Do not uninstall the APK if an app should be cached
16465                 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
16466                 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
16467                     // Other user still have this package installed, so all
16468                     // we need to do is clear this user's data and save that
16469                     // it is uninstalled.
16470                     if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
16471                     if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16472                         return false;
16473                     }
16474                     scheduleWritePackageRestrictionsLocked(user);
16475                     return true;
16476                 } else {
16477                     // We need to set it back to 'installed' so the uninstall
16478                     // broadcasts will be sent correctly.
16479                     if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
16480                     ps.setInstalled(true, user.getIdentifier());
16481                 }
16482             } else {
16483                 // This is a system app, so we assume that the
16484                 // other users still have this package installed, so all
16485                 // we need to do is clear this user's data and save that
16486                 // it is uninstalled.
16487                 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
16488                 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16489                     return false;
16490                 }
16491                 scheduleWritePackageRestrictionsLocked(user);
16492                 return true;
16493             }
16494         }
16495
16496         // If we are deleting a composite package for all users, keep track
16497         // of result for each child.
16498         if (ps.childPackageNames != null && outInfo != null) {
16499             synchronized (mPackages) {
16500                 final int childCount = ps.childPackageNames.size();
16501                 outInfo.removedChildPackages = new ArrayMap<>(childCount);
16502                 for (int i = 0; i < childCount; i++) {
16503                     String childPackageName = ps.childPackageNames.get(i);
16504                     PackageRemovedInfo childInfo = new PackageRemovedInfo();
16505                     childInfo.removedPackage = childPackageName;
16506                     outInfo.removedChildPackages.put(childPackageName, childInfo);
16507                     PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16508                     if (childPs != null) {
16509                         childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
16510                     }
16511                 }
16512             }
16513         }
16514
16515         boolean ret = false;
16516         if (isSystemApp(ps)) {
16517             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
16518             // When an updated system application is deleted we delete the existing resources
16519             // as well and fall back to existing code in system partition
16520             ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
16521         } else {
16522             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
16523             ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
16524                     outInfo, writeSettings, replacingPackage);
16525         }
16526
16527         // Take a note whether we deleted the package for all users
16528         if (outInfo != null) {
16529             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16530             if (outInfo.removedChildPackages != null) {
16531                 synchronized (mPackages) {
16532                     final int childCount = outInfo.removedChildPackages.size();
16533                     for (int i = 0; i < childCount; i++) {
16534                         PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
16535                         if (childInfo != null) {
16536                             childInfo.removedForAllUsers = mPackages.get(
16537                                     childInfo.removedPackage) == null;
16538                         }
16539                     }
16540                 }
16541             }
16542             // If we uninstalled an update to a system app there may be some
16543             // child packages that appeared as they are declared in the system
16544             // app but were not declared in the update.
16545             if (isSystemApp(ps)) {
16546                 synchronized (mPackages) {
16547                     PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name);
16548                     final int childCount = (updatedPs.childPackageNames != null)
16549                             ? updatedPs.childPackageNames.size() : 0;
16550                     for (int i = 0; i < childCount; i++) {
16551                         String childPackageName = updatedPs.childPackageNames.get(i);
16552                         if (outInfo.removedChildPackages == null
16553                                 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
16554                             PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16555                             if (childPs == null) {
16556                                 continue;
16557                             }
16558                             PackageInstalledInfo installRes = new PackageInstalledInfo();
16559                             installRes.name = childPackageName;
16560                             installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
16561                             installRes.pkg = mPackages.get(childPackageName);
16562                             installRes.uid = childPs.pkg.applicationInfo.uid;
16563                             if (outInfo.appearedChildPackages == null) {
16564                                 outInfo.appearedChildPackages = new ArrayMap<>();
16565                             }
16566                             outInfo.appearedChildPackages.put(childPackageName, installRes);
16567                         }
16568                     }
16569                 }
16570             }
16571         }
16572
16573         return ret;
16574     }
16575
16576     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
16577         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
16578                 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
16579         for (int nextUserId : userIds) {
16580             if (DEBUG_REMOVE) {
16581                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
16582             }
16583             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
16584                     false /*installed*/, true /*stopped*/, true /*notLaunched*/,
16585                     false /*hidden*/, false /*suspended*/, null, null, null,
16586                     false /*blockUninstall*/,
16587                     ps.readUserState(nextUserId).domainVerificationStatus, 0);
16588         }
16589     }
16590
16591     private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
16592             PackageRemovedInfo outInfo) {
16593         final PackageParser.Package pkg;
16594         synchronized (mPackages) {
16595             pkg = mPackages.get(ps.name);
16596         }
16597
16598         final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
16599                 : new int[] {userId};
16600         for (int nextUserId : userIds) {
16601             if (DEBUG_REMOVE) {
16602                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
16603                         + nextUserId);
16604             }
16605
16606             destroyAppDataLIF(pkg, userId,
16607                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16608             destroyAppProfilesLIF(pkg, userId);
16609             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
16610             schedulePackageCleaning(ps.name, nextUserId, false);
16611             synchronized (mPackages) {
16612                 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
16613                     scheduleWritePackageRestrictionsLocked(nextUserId);
16614                 }
16615                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
16616             }
16617         }
16618
16619         if (outInfo != null) {
16620             outInfo.removedPackage = ps.name;
16621             outInfo.removedAppId = ps.appId;
16622             outInfo.removedUsers = userIds;
16623         }
16624
16625         return true;
16626     }
16627
16628     private final class ClearStorageConnection implements ServiceConnection {
16629         IMediaContainerService mContainerService;
16630
16631         @Override
16632         public void onServiceConnected(ComponentName name, IBinder service) {
16633             synchronized (this) {
16634                 mContainerService = IMediaContainerService.Stub.asInterface(service);
16635                 notifyAll();
16636             }
16637         }
16638
16639         @Override
16640         public void onServiceDisconnected(ComponentName name) {
16641         }
16642     }
16643
16644     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
16645         if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
16646
16647         final boolean mounted;
16648         if (Environment.isExternalStorageEmulated()) {
16649             mounted = true;
16650         } else {
16651             final String status = Environment.getExternalStorageState();
16652
16653             mounted = status.equals(Environment.MEDIA_MOUNTED)
16654                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
16655         }
16656
16657         if (!mounted) {
16658             return;
16659         }
16660
16661         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
16662         int[] users;
16663         if (userId == UserHandle.USER_ALL) {
16664             users = sUserManager.getUserIds();
16665         } else {
16666             users = new int[] { userId };
16667         }
16668         final ClearStorageConnection conn = new ClearStorageConnection();
16669         if (mContext.bindServiceAsUser(
16670                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
16671             try {
16672                 for (int curUser : users) {
16673                     long timeout = SystemClock.uptimeMillis() + 5000;
16674                     synchronized (conn) {
16675                         long now;
16676                         while (conn.mContainerService == null &&
16677                                 (now = SystemClock.uptimeMillis()) < timeout) {
16678                             try {
16679                                 conn.wait(timeout - now);
16680                             } catch (InterruptedException e) {
16681                             }
16682                         }
16683                     }
16684                     if (conn.mContainerService == null) {
16685                         return;
16686                     }
16687
16688                     final UserEnvironment userEnv = new UserEnvironment(curUser);
16689                     clearDirectory(conn.mContainerService,
16690                             userEnv.buildExternalStorageAppCacheDirs(packageName));
16691                     if (allData) {
16692                         clearDirectory(conn.mContainerService,
16693                                 userEnv.buildExternalStorageAppDataDirs(packageName));
16694                         clearDirectory(conn.mContainerService,
16695                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
16696                     }
16697                 }
16698             } finally {
16699                 mContext.unbindService(conn);
16700             }
16701         }
16702     }
16703
16704     @Override
16705     public void clearApplicationProfileData(String packageName) {
16706         enforceSystemOrRoot("Only the system can clear all profile data");
16707
16708         final PackageParser.Package pkg;
16709         synchronized (mPackages) {
16710             pkg = mPackages.get(packageName);
16711         }
16712
16713         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
16714             synchronized (mInstallLock) {
16715                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
16716                 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL,
16717                         true /* removeBaseMarker */);
16718             }
16719         }
16720     }
16721
16722     @Override
16723     public void clearApplicationUserData(final String packageName,
16724             final IPackageDataObserver observer, final int userId) {
16725         mContext.enforceCallingOrSelfPermission(
16726                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
16727
16728         enforceCrossUserPermission(Binder.getCallingUid(), userId,
16729                 true /* requireFullPermission */, false /* checkShell */, "clear application data");
16730
16731         if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
16732             throw new SecurityException("Cannot clear data for a protected package: "
16733                     + packageName);
16734         }
16735         // Queue up an async operation since the package deletion may take a little while.
16736         mHandler.post(new Runnable() {
16737             public void run() {
16738                 mHandler.removeCallbacks(this);
16739                 final boolean succeeded;
16740                 try (PackageFreezer freezer = freezePackage(packageName,
16741                         "clearApplicationUserData")) {
16742                     synchronized (mInstallLock) {
16743                         succeeded = clearApplicationUserDataLIF(packageName, userId);
16744                     }
16745                     clearExternalStorageDataSync(packageName, userId, true);
16746                 }
16747                 if (succeeded) {
16748                     // invoke DeviceStorageMonitor's update method to clear any notifications
16749                     DeviceStorageMonitorInternal dsm = LocalServices
16750                             .getService(DeviceStorageMonitorInternal.class);
16751                     if (dsm != null) {
16752                         dsm.checkMemory();
16753                     }
16754                 }
16755                 if(observer != null) {
16756                     try {
16757                         observer.onRemoveCompleted(packageName, succeeded);
16758                     } catch (RemoteException e) {
16759                         Log.i(TAG, "Observer no longer exists.");
16760                     }
16761                 } //end if observer
16762             } //end run
16763         });
16764     }
16765
16766     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
16767         if (packageName == null) {
16768             Slog.w(TAG, "Attempt to delete null packageName.");
16769             return false;
16770         }
16771
16772         // Try finding details about the requested package
16773         PackageParser.Package pkg;
16774         synchronized (mPackages) {
16775             pkg = mPackages.get(packageName);
16776             if (pkg == null) {
16777                 final PackageSetting ps = mSettings.mPackages.get(packageName);
16778                 if (ps != null) {
16779                     pkg = ps.pkg;
16780                 }
16781             }
16782
16783             if (pkg == null) {
16784                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16785                 return false;
16786             }
16787
16788             PackageSetting ps = (PackageSetting) pkg.mExtras;
16789             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16790         }
16791
16792         clearAppDataLIF(pkg, userId,
16793                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16794
16795         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16796         removeKeystoreDataIfNeeded(userId, appId);
16797
16798         UserManagerInternal umInternal = getUserManagerInternal();
16799         final int flags;
16800         if (umInternal.isUserUnlockingOrUnlocked(userId)) {
16801             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
16802         } else if (umInternal.isUserRunning(userId)) {
16803             flags = StorageManager.FLAG_STORAGE_DE;
16804         } else {
16805             flags = 0;
16806         }
16807         prepareAppDataContentsLIF(pkg, userId, flags);
16808
16809         return true;
16810     }
16811
16812     /**
16813      * Reverts user permission state changes (permissions and flags) in
16814      * all packages for a given user.
16815      *
16816      * @param userId The device user for which to do a reset.
16817      */
16818     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
16819         final int packageCount = mPackages.size();
16820         for (int i = 0; i < packageCount; i++) {
16821             PackageParser.Package pkg = mPackages.valueAt(i);
16822             PackageSetting ps = (PackageSetting) pkg.mExtras;
16823             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16824         }
16825     }
16826
16827     private void resetNetworkPolicies(int userId) {
16828         LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
16829     }
16830
16831     /**
16832      * Reverts user permission state changes (permissions and flags).
16833      *
16834      * @param ps The package for which to reset.
16835      * @param userId The device user for which to do a reset.
16836      */
16837     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
16838             final PackageSetting ps, final int userId) {
16839         if (ps.pkg == null) {
16840             return;
16841         }
16842
16843         // These are flags that can change base on user actions.
16844         final int userSettableMask = FLAG_PERMISSION_USER_SET
16845                 | FLAG_PERMISSION_USER_FIXED
16846                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
16847                 | FLAG_PERMISSION_REVIEW_REQUIRED;
16848
16849         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
16850                 | FLAG_PERMISSION_POLICY_FIXED;
16851
16852         boolean writeInstallPermissions = false;
16853         boolean writeRuntimePermissions = false;
16854
16855         final int permissionCount = ps.pkg.requestedPermissions.size();
16856         for (int i = 0; i < permissionCount; i++) {
16857             String permission = ps.pkg.requestedPermissions.get(i);
16858
16859             BasePermission bp = mSettings.mPermissions.get(permission);
16860             if (bp == null) {
16861                 continue;
16862             }
16863
16864             // If shared user we just reset the state to which only this app contributed.
16865             if (ps.sharedUser != null) {
16866                 boolean used = false;
16867                 final int packageCount = ps.sharedUser.packages.size();
16868                 for (int j = 0; j < packageCount; j++) {
16869                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
16870                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
16871                             && pkg.pkg.requestedPermissions.contains(permission)) {
16872                         used = true;
16873                         break;
16874                     }
16875                 }
16876                 if (used) {
16877                     continue;
16878                 }
16879             }
16880
16881             PermissionsState permissionsState = ps.getPermissionsState();
16882
16883             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
16884
16885             // Always clear the user settable flags.
16886             final boolean hasInstallState = permissionsState.getInstallPermissionState(
16887                     bp.name) != null;
16888             // If permission review is enabled and this is a legacy app, mark the
16889             // permission as requiring a review as this is the initial state.
16890             int flags = 0;
16891             if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
16892                     && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
16893                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
16894             }
16895             if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
16896                 if (hasInstallState) {
16897                     writeInstallPermissions = true;
16898                 } else {
16899                     writeRuntimePermissions = true;
16900                 }
16901             }
16902
16903             // Below is only runtime permission handling.
16904             if (!bp.isRuntime()) {
16905                 continue;
16906             }
16907
16908             // Never clobber system or policy.
16909             if ((oldFlags & policyOrSystemFlags) != 0) {
16910                 continue;
16911             }
16912
16913             // If this permission was granted by default, make sure it is.
16914             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
16915                 if (permissionsState.grantRuntimePermission(bp, userId)
16916                         != PERMISSION_OPERATION_FAILURE) {
16917                     writeRuntimePermissions = true;
16918                 }
16919             // If permission review is enabled the permissions for a legacy apps
16920             // are represented as constantly granted runtime ones, so don't revoke.
16921             } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
16922                 // Otherwise, reset the permission.
16923                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
16924                 switch (revokeResult) {
16925                     case PERMISSION_OPERATION_SUCCESS:
16926                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
16927                         writeRuntimePermissions = true;
16928                         final int appId = ps.appId;
16929                         mHandler.post(new Runnable() {
16930                             @Override
16931                             public void run() {
16932                                 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
16933                             }
16934                         });
16935                     } break;
16936                 }
16937             }
16938         }
16939
16940         // Synchronously write as we are taking permissions away.
16941         if (writeRuntimePermissions) {
16942             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
16943         }
16944
16945         // Synchronously write as we are taking permissions away.
16946         if (writeInstallPermissions) {
16947             mSettings.writeLPr();
16948         }
16949     }
16950
16951     /**
16952      * Remove entries from the keystore daemon. Will only remove it if the
16953      * {@code appId} is valid.
16954      */
16955     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
16956         if (appId < 0) {
16957             return;
16958         }
16959
16960         final KeyStore keyStore = KeyStore.getInstance();
16961         if (keyStore != null) {
16962             if (userId == UserHandle.USER_ALL) {
16963                 for (final int individual : sUserManager.getUserIds()) {
16964                     keyStore.clearUid(UserHandle.getUid(individual, appId));
16965                 }
16966             } else {
16967                 keyStore.clearUid(UserHandle.getUid(userId, appId));
16968             }
16969         } else {
16970             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
16971         }
16972     }
16973
16974     @Override
16975     public void deleteApplicationCacheFiles(final String packageName,
16976             final IPackageDataObserver observer) {
16977         final int userId = UserHandle.getCallingUserId();
16978         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
16979     }
16980
16981     @Override
16982     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
16983             final IPackageDataObserver observer) {
16984         mContext.enforceCallingOrSelfPermission(
16985                 android.Manifest.permission.DELETE_CACHE_FILES, null);
16986         enforceCrossUserPermission(Binder.getCallingUid(), userId,
16987                 /* requireFullPermission= */ true, /* checkShell= */ false,
16988                 "delete application cache files");
16989
16990         final PackageParser.Package pkg;
16991         synchronized (mPackages) {
16992             pkg = mPackages.get(packageName);
16993         }
16994
16995         // Queue up an async operation since the package deletion may take a little while.
16996         mHandler.post(new Runnable() {
16997             public void run() {
16998                 synchronized (mInstallLock) {
16999                     final int flags = StorageManager.FLAG_STORAGE_DE
17000                             | StorageManager.FLAG_STORAGE_CE;
17001                     // We're only clearing cache files, so we don't care if the
17002                     // app is unfrozen and still able to run
17003                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
17004                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17005                 }
17006                 clearExternalStorageDataSync(packageName, userId, false);
17007                 if (observer != null) {
17008                     try {
17009                         observer.onRemoveCompleted(packageName, true);
17010                     } catch (RemoteException e) {
17011                         Log.i(TAG, "Observer no longer exists.");
17012                     }
17013                 }
17014             }
17015         });
17016     }
17017
17018     @Override
17019     public void getPackageSizeInfo(final String packageName, int userHandle,
17020             final IPackageStatsObserver observer) {
17021         mContext.enforceCallingOrSelfPermission(
17022                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
17023         if (packageName == null) {
17024             throw new IllegalArgumentException("Attempt to get size of null packageName");
17025         }
17026
17027         PackageStats stats = new PackageStats(packageName, userHandle);
17028
17029         /*
17030          * Queue up an async operation since the package measurement may take a
17031          * little while.
17032          */
17033         Message msg = mHandler.obtainMessage(INIT_COPY);
17034         msg.obj = new MeasureParams(stats, observer);
17035         mHandler.sendMessage(msg);
17036     }
17037
17038     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
17039         final PackageSetting ps;
17040         synchronized (mPackages) {
17041             ps = mSettings.mPackages.get(packageName);
17042             if (ps == null) {
17043                 Slog.w(TAG, "Failed to find settings for " + packageName);
17044                 return false;
17045             }
17046         }
17047         try {
17048             mInstaller.getAppSize(ps.volumeUuid, packageName, userId,
17049                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE,
17050                     ps.getCeDataInode(userId), ps.codePathString, stats);
17051         } catch (InstallerException e) {
17052             Slog.w(TAG, String.valueOf(e));
17053             return false;
17054         }
17055
17056         // For now, ignore code size of packages on system partition
17057         if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
17058             stats.codeSize = 0;
17059         }
17060
17061         return true;
17062     }
17063
17064     private int getUidTargetSdkVersionLockedLPr(int uid) {
17065         Object obj = mSettings.getUserIdLPr(uid);
17066         if (obj instanceof SharedUserSetting) {
17067             final SharedUserSetting sus = (SharedUserSetting) obj;
17068             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
17069             final Iterator<PackageSetting> it = sus.packages.iterator();
17070             while (it.hasNext()) {
17071                 final PackageSetting ps = it.next();
17072                 if (ps.pkg != null) {
17073                     int v = ps.pkg.applicationInfo.targetSdkVersion;
17074                     if (v < vers) vers = v;
17075                 }
17076             }
17077             return vers;
17078         } else if (obj instanceof PackageSetting) {
17079             final PackageSetting ps = (PackageSetting) obj;
17080             if (ps.pkg != null) {
17081                 return ps.pkg.applicationInfo.targetSdkVersion;
17082             }
17083         }
17084         return Build.VERSION_CODES.CUR_DEVELOPMENT;
17085     }
17086
17087     @Override
17088     public void addPreferredActivity(IntentFilter filter, int match,
17089             ComponentName[] set, ComponentName activity, int userId) {
17090         addPreferredActivityInternal(filter, match, set, activity, true, userId,
17091                 "Adding preferred");
17092     }
17093
17094     private void addPreferredActivityInternal(IntentFilter filter, int match,
17095             ComponentName[] set, ComponentName activity, boolean always, int userId,
17096             String opname) {
17097         // writer
17098         int callingUid = Binder.getCallingUid();
17099         enforceCrossUserPermission(callingUid, userId,
17100                 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
17101         if (filter.countActions() == 0) {
17102             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
17103             return;
17104         }
17105         synchronized (mPackages) {
17106             if (mContext.checkCallingOrSelfPermission(
17107                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17108                     != PackageManager.PERMISSION_GRANTED) {
17109                 if (getUidTargetSdkVersionLockedLPr(callingUid)
17110                         < Build.VERSION_CODES.FROYO) {
17111                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
17112                             + callingUid);
17113                     return;
17114                 }
17115                 mContext.enforceCallingOrSelfPermission(
17116                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17117             }
17118
17119             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
17120             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
17121                     + userId + ":");
17122             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17123             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
17124             scheduleWritePackageRestrictionsLocked(userId);
17125             postPreferredActivityChangedBroadcast(userId);
17126         }
17127     }
17128
17129     private void postPreferredActivityChangedBroadcast(int userId) {
17130         mHandler.post(() -> {
17131             final IActivityManager am = ActivityManagerNative.getDefault();
17132             if (am == null) {
17133                 return;
17134             }
17135
17136             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
17137             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17138             try {
17139                 am.broadcastIntent(null, intent, null, null,
17140                         0, null, null, null, android.app.AppOpsManager.OP_NONE,
17141                         null, false, false, userId);
17142             } catch (RemoteException e) {
17143             }
17144         });
17145     }
17146
17147     @Override
17148     public void replacePreferredActivity(IntentFilter filter, int match,
17149             ComponentName[] set, ComponentName activity, int userId) {
17150         if (filter.countActions() != 1) {
17151             throw new IllegalArgumentException(
17152                     "replacePreferredActivity expects filter to have only 1 action.");
17153         }
17154         if (filter.countDataAuthorities() != 0
17155                 || filter.countDataPaths() != 0
17156                 || filter.countDataSchemes() > 1
17157                 || filter.countDataTypes() != 0) {
17158             throw new IllegalArgumentException(
17159                     "replacePreferredActivity expects filter to have no data authorities, " +
17160                     "paths, or types; and at most one scheme.");
17161         }
17162
17163         final int callingUid = Binder.getCallingUid();
17164         enforceCrossUserPermission(callingUid, userId,
17165                 true /* requireFullPermission */, false /* checkShell */,
17166                 "replace preferred activity");
17167         synchronized (mPackages) {
17168             if (mContext.checkCallingOrSelfPermission(
17169                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17170                     != PackageManager.PERMISSION_GRANTED) {
17171                 if (getUidTargetSdkVersionLockedLPr(callingUid)
17172                         < Build.VERSION_CODES.FROYO) {
17173                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
17174                             + Binder.getCallingUid());
17175                     return;
17176                 }
17177                 mContext.enforceCallingOrSelfPermission(
17178                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17179             }
17180
17181             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
17182             if (pir != null) {
17183                 // Get all of the existing entries that exactly match this filter.
17184                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
17185                 if (existing != null && existing.size() == 1) {
17186                     PreferredActivity cur = existing.get(0);
17187                     if (DEBUG_PREFERRED) {
17188                         Slog.i(TAG, "Checking replace of preferred:");
17189                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17190                         if (!cur.mPref.mAlways) {
17191                             Slog.i(TAG, "  -- CUR; not mAlways!");
17192                         } else {
17193                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
17194                             Slog.i(TAG, "  -- CUR: mSet="
17195                                     + Arrays.toString(cur.mPref.mSetComponents));
17196                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
17197                             Slog.i(TAG, "  -- NEW: mMatch="
17198                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
17199                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
17200                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
17201                         }
17202                     }
17203                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
17204                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
17205                             && cur.mPref.sameSet(set)) {
17206                         // Setting the preferred activity to what it happens to be already
17207                         if (DEBUG_PREFERRED) {
17208                             Slog.i(TAG, "Replacing with same preferred activity "
17209                                     + cur.mPref.mShortComponent + " for user "
17210                                     + userId + ":");
17211                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17212                         }
17213                         return;
17214                     }
17215                 }
17216
17217                 if (existing != null) {
17218                     if (DEBUG_PREFERRED) {
17219                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
17220                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17221                     }
17222                     for (int i = 0; i < existing.size(); i++) {
17223                         PreferredActivity pa = existing.get(i);
17224                         if (DEBUG_PREFERRED) {
17225                             Slog.i(TAG, "Removing existing preferred activity "
17226                                     + pa.mPref.mComponent + ":");
17227                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
17228                         }
17229                         pir.removeFilter(pa);
17230                     }
17231                 }
17232             }
17233             addPreferredActivityInternal(filter, match, set, activity, true, userId,
17234                     "Replacing preferred");
17235         }
17236     }
17237
17238     @Override
17239     public void clearPackagePreferredActivities(String packageName) {
17240         final int uid = Binder.getCallingUid();
17241         // writer
17242         synchronized (mPackages) {
17243             PackageParser.Package pkg = mPackages.get(packageName);
17244             if (pkg == null || pkg.applicationInfo.uid != uid) {
17245                 if (mContext.checkCallingOrSelfPermission(
17246                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17247                         != PackageManager.PERMISSION_GRANTED) {
17248                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
17249                             < Build.VERSION_CODES.FROYO) {
17250                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
17251                                 + Binder.getCallingUid());
17252                         return;
17253                     }
17254                     mContext.enforceCallingOrSelfPermission(
17255                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17256                 }
17257             }
17258
17259             int user = UserHandle.getCallingUserId();
17260             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
17261                 scheduleWritePackageRestrictionsLocked(user);
17262             }
17263         }
17264     }
17265
17266     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17267     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
17268         ArrayList<PreferredActivity> removed = null;
17269         boolean changed = false;
17270         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
17271             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
17272             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
17273             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
17274                 continue;
17275             }
17276             Iterator<PreferredActivity> it = pir.filterIterator();
17277             while (it.hasNext()) {
17278                 PreferredActivity pa = it.next();
17279                 // Mark entry for removal only if it matches the package name
17280                 // and the entry is of type "always".
17281                 if (packageName == null ||
17282                         (pa.mPref.mComponent.getPackageName().equals(packageName)
17283                                 && pa.mPref.mAlways)) {
17284                     if (removed == null) {
17285                         removed = new ArrayList<PreferredActivity>();
17286                     }
17287                     removed.add(pa);
17288                 }
17289             }
17290             if (removed != null) {
17291                 for (int j=0; j<removed.size(); j++) {
17292                     PreferredActivity pa = removed.get(j);
17293                     pir.removeFilter(pa);
17294                 }
17295                 changed = true;
17296             }
17297         }
17298         if (changed) {
17299             postPreferredActivityChangedBroadcast(userId);
17300         }
17301         return changed;
17302     }
17303
17304     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17305     private void clearIntentFilterVerificationsLPw(int userId) {
17306         final int packageCount = mPackages.size();
17307         for (int i = 0; i < packageCount; i++) {
17308             PackageParser.Package pkg = mPackages.valueAt(i);
17309             clearIntentFilterVerificationsLPw(pkg.packageName, userId);
17310         }
17311     }
17312
17313     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17314     void clearIntentFilterVerificationsLPw(String packageName, int userId) {
17315         if (userId == UserHandle.USER_ALL) {
17316             if (mSettings.removeIntentFilterVerificationLPw(packageName,
17317                     sUserManager.getUserIds())) {
17318                 for (int oneUserId : sUserManager.getUserIds()) {
17319                     scheduleWritePackageRestrictionsLocked(oneUserId);
17320                 }
17321             }
17322         } else {
17323             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
17324                 scheduleWritePackageRestrictionsLocked(userId);
17325             }
17326         }
17327     }
17328
17329     void clearDefaultBrowserIfNeeded(String packageName) {
17330         for (int oneUserId : sUserManager.getUserIds()) {
17331             String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
17332             if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
17333             if (packageName.equals(defaultBrowserPackageName)) {
17334                 setDefaultBrowserPackageName(null, oneUserId);
17335             }
17336         }
17337     }
17338
17339     @Override
17340     public void resetApplicationPreferences(int userId) {
17341         mContext.enforceCallingOrSelfPermission(
17342                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17343         final long identity = Binder.clearCallingIdentity();
17344         // writer
17345         try {
17346             synchronized (mPackages) {
17347                 clearPackagePreferredActivitiesLPw(null, userId);
17348                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
17349                 // TODO: We have to reset the default SMS and Phone. This requires
17350                 // significant refactoring to keep all default apps in the package
17351                 // manager (cleaner but more work) or have the services provide
17352                 // callbacks to the package manager to request a default app reset.
17353                 applyFactoryDefaultBrowserLPw(userId);
17354                 clearIntentFilterVerificationsLPw(userId);
17355                 primeDomainVerificationsLPw(userId);
17356                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
17357                 scheduleWritePackageRestrictionsLocked(userId);
17358             }
17359             resetNetworkPolicies(userId);
17360         } finally {
17361             Binder.restoreCallingIdentity(identity);
17362         }
17363     }
17364
17365     @Override
17366     public int getPreferredActivities(List<IntentFilter> outFilters,
17367             List<ComponentName> outActivities, String packageName) {
17368
17369         int num = 0;
17370         final int userId = UserHandle.getCallingUserId();
17371         // reader
17372         synchronized (mPackages) {
17373             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
17374             if (pir != null) {
17375                 final Iterator<PreferredActivity> it = pir.filterIterator();
17376                 while (it.hasNext()) {
17377                     final PreferredActivity pa = it.next();
17378                     if (packageName == null
17379                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
17380                                     && pa.mPref.mAlways)) {
17381                         if (outFilters != null) {
17382                             outFilters.add(new IntentFilter(pa));
17383                         }
17384                         if (outActivities != null) {
17385                             outActivities.add(pa.mPref.mComponent);
17386                         }
17387                     }
17388                 }
17389             }
17390         }
17391
17392         return num;
17393     }
17394
17395     @Override
17396     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
17397             int userId) {
17398         int callingUid = Binder.getCallingUid();
17399         if (callingUid != Process.SYSTEM_UID) {
17400             throw new SecurityException(
17401                     "addPersistentPreferredActivity can only be run by the system");
17402         }
17403         if (filter.countActions() == 0) {
17404             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
17405             return;
17406         }
17407         synchronized (mPackages) {
17408             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
17409                     ":");
17410             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17411             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
17412                     new PersistentPreferredActivity(filter, activity));
17413             scheduleWritePackageRestrictionsLocked(userId);
17414             postPreferredActivityChangedBroadcast(userId);
17415         }
17416     }
17417
17418     @Override
17419     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
17420         int callingUid = Binder.getCallingUid();
17421         if (callingUid != Process.SYSTEM_UID) {
17422             throw new SecurityException(
17423                     "clearPackagePersistentPreferredActivities can only be run by the system");
17424         }
17425         ArrayList<PersistentPreferredActivity> removed = null;
17426         boolean changed = false;
17427         synchronized (mPackages) {
17428             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
17429                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
17430                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
17431                         .valueAt(i);
17432                 if (userId != thisUserId) {
17433                     continue;
17434                 }
17435                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
17436                 while (it.hasNext()) {
17437                     PersistentPreferredActivity ppa = it.next();
17438                     // Mark entry for removal only if it matches the package name.
17439                     if (ppa.mComponent.getPackageName().equals(packageName)) {
17440                         if (removed == null) {
17441                             removed = new ArrayList<PersistentPreferredActivity>();
17442                         }
17443                         removed.add(ppa);
17444                     }
17445                 }
17446                 if (removed != null) {
17447                     for (int j=0; j<removed.size(); j++) {
17448                         PersistentPreferredActivity ppa = removed.get(j);
17449                         ppir.removeFilter(ppa);
17450                     }
17451                     changed = true;
17452                 }
17453             }
17454
17455             if (changed) {
17456                 scheduleWritePackageRestrictionsLocked(userId);
17457                 postPreferredActivityChangedBroadcast(userId);
17458             }
17459         }
17460     }
17461
17462     /**
17463      * Common machinery for picking apart a restored XML blob and passing
17464      * it to a caller-supplied functor to be applied to the running system.
17465      */
17466     private void restoreFromXml(XmlPullParser parser, int userId,
17467             String expectedStartTag, BlobXmlRestorer functor)
17468             throws IOException, XmlPullParserException {
17469         int type;
17470         while ((type = parser.next()) != XmlPullParser.START_TAG
17471                 && type != XmlPullParser.END_DOCUMENT) {
17472         }
17473         if (type != XmlPullParser.START_TAG) {
17474             // oops didn't find a start tag?!
17475             if (DEBUG_BACKUP) {
17476                 Slog.e(TAG, "Didn't find start tag during restore");
17477             }
17478             return;
17479         }
17480 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
17481         // this is supposed to be TAG_PREFERRED_BACKUP
17482         if (!expectedStartTag.equals(parser.getName())) {
17483             if (DEBUG_BACKUP) {
17484                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
17485             }
17486             return;
17487         }
17488
17489         // skip interfering stuff, then we're aligned with the backing implementation
17490         while ((type = parser.next()) == XmlPullParser.TEXT) { }
17491 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
17492         functor.apply(parser, userId);
17493     }
17494
17495     private interface BlobXmlRestorer {
17496         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
17497     }
17498
17499     /**
17500      * Non-Binder method, support for the backup/restore mechanism: write the
17501      * full set of preferred activities in its canonical XML format.  Returns the
17502      * XML output as a byte array, or null if there is none.
17503      */
17504     @Override
17505     public byte[] getPreferredActivityBackup(int userId) {
17506         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17507             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
17508         }
17509
17510         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17511         try {
17512             final XmlSerializer serializer = new FastXmlSerializer();
17513             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17514             serializer.startDocument(null, true);
17515             serializer.startTag(null, TAG_PREFERRED_BACKUP);
17516
17517             synchronized (mPackages) {
17518                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
17519             }
17520
17521             serializer.endTag(null, TAG_PREFERRED_BACKUP);
17522             serializer.endDocument();
17523             serializer.flush();
17524         } catch (Exception e) {
17525             if (DEBUG_BACKUP) {
17526                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
17527             }
17528             return null;
17529         }
17530
17531         return dataStream.toByteArray();
17532     }
17533
17534     @Override
17535     public void restorePreferredActivities(byte[] backup, int userId) {
17536         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17537             throw new SecurityException("Only the system may call restorePreferredActivities()");
17538         }
17539
17540         try {
17541             final XmlPullParser parser = Xml.newPullParser();
17542             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17543             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
17544                     new BlobXmlRestorer() {
17545                         @Override
17546                         public void apply(XmlPullParser parser, int userId)
17547                                 throws XmlPullParserException, IOException {
17548                             synchronized (mPackages) {
17549                                 mSettings.readPreferredActivitiesLPw(parser, userId);
17550                             }
17551                         }
17552                     } );
17553         } catch (Exception e) {
17554             if (DEBUG_BACKUP) {
17555                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17556             }
17557         }
17558     }
17559
17560     /**
17561      * Non-Binder method, support for the backup/restore mechanism: write the
17562      * default browser (etc) settings in its canonical XML format.  Returns the default
17563      * browser XML representation as a byte array, or null if there is none.
17564      */
17565     @Override
17566     public byte[] getDefaultAppsBackup(int userId) {
17567         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17568             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
17569         }
17570
17571         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17572         try {
17573             final XmlSerializer serializer = new FastXmlSerializer();
17574             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17575             serializer.startDocument(null, true);
17576             serializer.startTag(null, TAG_DEFAULT_APPS);
17577
17578             synchronized (mPackages) {
17579                 mSettings.writeDefaultAppsLPr(serializer, userId);
17580             }
17581
17582             serializer.endTag(null, TAG_DEFAULT_APPS);
17583             serializer.endDocument();
17584             serializer.flush();
17585         } catch (Exception e) {
17586             if (DEBUG_BACKUP) {
17587                 Slog.e(TAG, "Unable to write default apps for backup", e);
17588             }
17589             return null;
17590         }
17591
17592         return dataStream.toByteArray();
17593     }
17594
17595     @Override
17596     public void restoreDefaultApps(byte[] backup, int userId) {
17597         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17598             throw new SecurityException("Only the system may call restoreDefaultApps()");
17599         }
17600
17601         try {
17602             final XmlPullParser parser = Xml.newPullParser();
17603             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17604             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
17605                     new BlobXmlRestorer() {
17606                         @Override
17607                         public void apply(XmlPullParser parser, int userId)
17608                                 throws XmlPullParserException, IOException {
17609                             synchronized (mPackages) {
17610                                 mSettings.readDefaultAppsLPw(parser, userId);
17611                             }
17612                         }
17613                     } );
17614         } catch (Exception e) {
17615             if (DEBUG_BACKUP) {
17616                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
17617             }
17618         }
17619     }
17620
17621     @Override
17622     public byte[] getIntentFilterVerificationBackup(int userId) {
17623         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17624             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
17625         }
17626
17627         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17628         try {
17629             final XmlSerializer serializer = new FastXmlSerializer();
17630             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17631             serializer.startDocument(null, true);
17632             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
17633
17634             synchronized (mPackages) {
17635                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
17636             }
17637
17638             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
17639             serializer.endDocument();
17640             serializer.flush();
17641         } catch (Exception e) {
17642             if (DEBUG_BACKUP) {
17643                 Slog.e(TAG, "Unable to write default apps for backup", e);
17644             }
17645             return null;
17646         }
17647
17648         return dataStream.toByteArray();
17649     }
17650
17651     @Override
17652     public void restoreIntentFilterVerification(byte[] backup, int userId) {
17653         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17654             throw new SecurityException("Only the system may call restorePreferredActivities()");
17655         }
17656
17657         try {
17658             final XmlPullParser parser = Xml.newPullParser();
17659             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17660             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
17661                     new BlobXmlRestorer() {
17662                         @Override
17663                         public void apply(XmlPullParser parser, int userId)
17664                                 throws XmlPullParserException, IOException {
17665                             synchronized (mPackages) {
17666                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
17667                                 mSettings.writeLPr();
17668                             }
17669                         }
17670                     } );
17671         } catch (Exception e) {
17672             if (DEBUG_BACKUP) {
17673                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17674             }
17675         }
17676     }
17677
17678     @Override
17679     public byte[] getPermissionGrantBackup(int userId) {
17680         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17681             throw new SecurityException("Only the system may call getPermissionGrantBackup()");
17682         }
17683
17684         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17685         try {
17686             final XmlSerializer serializer = new FastXmlSerializer();
17687             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17688             serializer.startDocument(null, true);
17689             serializer.startTag(null, TAG_PERMISSION_BACKUP);
17690
17691             synchronized (mPackages) {
17692                 serializeRuntimePermissionGrantsLPr(serializer, userId);
17693             }
17694
17695             serializer.endTag(null, TAG_PERMISSION_BACKUP);
17696             serializer.endDocument();
17697             serializer.flush();
17698         } catch (Exception e) {
17699             if (DEBUG_BACKUP) {
17700                 Slog.e(TAG, "Unable to write default apps for backup", e);
17701             }
17702             return null;
17703         }
17704
17705         return dataStream.toByteArray();
17706     }
17707
17708     @Override
17709     public void restorePermissionGrants(byte[] backup, int userId) {
17710         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17711             throw new SecurityException("Only the system may call restorePermissionGrants()");
17712         }
17713
17714         try {
17715             final XmlPullParser parser = Xml.newPullParser();
17716             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17717             restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
17718                     new BlobXmlRestorer() {
17719                         @Override
17720                         public void apply(XmlPullParser parser, int userId)
17721                                 throws XmlPullParserException, IOException {
17722                             synchronized (mPackages) {
17723                                 processRestoredPermissionGrantsLPr(parser, userId);
17724                             }
17725                         }
17726                     } );
17727         } catch (Exception e) {
17728             if (DEBUG_BACKUP) {
17729                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17730             }
17731         }
17732     }
17733
17734     private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
17735             throws IOException {
17736         serializer.startTag(null, TAG_ALL_GRANTS);
17737
17738         final int N = mSettings.mPackages.size();
17739         for (int i = 0; i < N; i++) {
17740             final PackageSetting ps = mSettings.mPackages.valueAt(i);
17741             boolean pkgGrantsKnown = false;
17742
17743             PermissionsState packagePerms = ps.getPermissionsState();
17744
17745             for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
17746                 final int grantFlags = state.getFlags();
17747                 // only look at grants that are not system/policy fixed
17748                 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
17749                     final boolean isGranted = state.isGranted();
17750                     // And only back up the user-twiddled state bits
17751                     if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
17752                         final String packageName = mSettings.mPackages.keyAt(i);
17753                         if (!pkgGrantsKnown) {
17754                             serializer.startTag(null, TAG_GRANT);
17755                             serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
17756                             pkgGrantsKnown = true;
17757                         }
17758
17759                         final boolean userSet =
17760                                 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
17761                         final boolean userFixed =
17762                                 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
17763                         final boolean revoke =
17764                                 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
17765
17766                         serializer.startTag(null, TAG_PERMISSION);
17767                         serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
17768                         if (isGranted) {
17769                             serializer.attribute(null, ATTR_IS_GRANTED, "true");
17770                         }
17771                         if (userSet) {
17772                             serializer.attribute(null, ATTR_USER_SET, "true");
17773                         }
17774                         if (userFixed) {
17775                             serializer.attribute(null, ATTR_USER_FIXED, "true");
17776                         }
17777                         if (revoke) {
17778                             serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
17779                         }
17780                         serializer.endTag(null, TAG_PERMISSION);
17781                     }
17782                 }
17783             }
17784
17785             if (pkgGrantsKnown) {
17786                 serializer.endTag(null, TAG_GRANT);
17787             }
17788         }
17789
17790         serializer.endTag(null, TAG_ALL_GRANTS);
17791     }
17792
17793     private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
17794             throws XmlPullParserException, IOException {
17795         String pkgName = null;
17796         int outerDepth = parser.getDepth();
17797         int type;
17798         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
17799                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
17800             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
17801                 continue;
17802             }
17803
17804             final String tagName = parser.getName();
17805             if (tagName.equals(TAG_GRANT)) {
17806                 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
17807                 if (DEBUG_BACKUP) {
17808                     Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
17809                 }
17810             } else if (tagName.equals(TAG_PERMISSION)) {
17811
17812                 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
17813                 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
17814
17815                 int newFlagSet = 0;
17816                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
17817                     newFlagSet |= FLAG_PERMISSION_USER_SET;
17818                 }
17819                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
17820                     newFlagSet |= FLAG_PERMISSION_USER_FIXED;
17821                 }
17822                 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
17823                     newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
17824                 }
17825                 if (DEBUG_BACKUP) {
17826                     Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
17827                             + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
17828                 }
17829                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17830                 if (ps != null) {
17831                     // Already installed so we apply the grant immediately
17832                     if (DEBUG_BACKUP) {
17833                         Slog.v(TAG, "        + already installed; applying");
17834                     }
17835                     PermissionsState perms = ps.getPermissionsState();
17836                     BasePermission bp = mSettings.mPermissions.get(permName);
17837                     if (bp != null) {
17838                         if (isGranted) {
17839                             perms.grantRuntimePermission(bp, userId);
17840                         }
17841                         if (newFlagSet != 0) {
17842                             perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
17843                         }
17844                     }
17845                 } else {
17846                     // Need to wait for post-restore install to apply the grant
17847                     if (DEBUG_BACKUP) {
17848                         Slog.v(TAG, "        - not yet installed; saving for later");
17849                     }
17850                     mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
17851                             isGranted, newFlagSet, userId);
17852                 }
17853             } else {
17854                 PackageManagerService.reportSettingsProblem(Log.WARN,
17855                         "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
17856                 XmlUtils.skipCurrentTag(parser);
17857             }
17858         }
17859
17860         scheduleWriteSettingsLocked();
17861         mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17862     }
17863
17864     @Override
17865     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
17866             int sourceUserId, int targetUserId, int flags) {
17867         mContext.enforceCallingOrSelfPermission(
17868                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17869         int callingUid = Binder.getCallingUid();
17870         enforceOwnerRights(ownerPackage, callingUid);
17871         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17872         if (intentFilter.countActions() == 0) {
17873             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
17874             return;
17875         }
17876         synchronized (mPackages) {
17877             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
17878                     ownerPackage, targetUserId, flags);
17879             CrossProfileIntentResolver resolver =
17880                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17881             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
17882             // We have all those whose filter is equal. Now checking if the rest is equal as well.
17883             if (existing != null) {
17884                 int size = existing.size();
17885                 for (int i = 0; i < size; i++) {
17886                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
17887                         return;
17888                     }
17889                 }
17890             }
17891             resolver.addFilter(newFilter);
17892             scheduleWritePackageRestrictionsLocked(sourceUserId);
17893         }
17894     }
17895
17896     @Override
17897     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
17898         mContext.enforceCallingOrSelfPermission(
17899                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17900         int callingUid = Binder.getCallingUid();
17901         enforceOwnerRights(ownerPackage, callingUid);
17902         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17903         synchronized (mPackages) {
17904             CrossProfileIntentResolver resolver =
17905                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17906             ArraySet<CrossProfileIntentFilter> set =
17907                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
17908             for (CrossProfileIntentFilter filter : set) {
17909                 if (filter.getOwnerPackage().equals(ownerPackage)) {
17910                     resolver.removeFilter(filter);
17911                 }
17912             }
17913             scheduleWritePackageRestrictionsLocked(sourceUserId);
17914         }
17915     }
17916
17917     // Enforcing that callingUid is owning pkg on userId
17918     private void enforceOwnerRights(String pkg, int callingUid) {
17919         // The system owns everything.
17920         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17921             return;
17922         }
17923         int callingUserId = UserHandle.getUserId(callingUid);
17924         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
17925         if (pi == null) {
17926             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
17927                     + callingUserId);
17928         }
17929         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
17930             throw new SecurityException("Calling uid " + callingUid
17931                     + " does not own package " + pkg);
17932         }
17933     }
17934
17935     @Override
17936     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
17937         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
17938     }
17939
17940     private Intent getHomeIntent() {
17941         Intent intent = new Intent(Intent.ACTION_MAIN);
17942         intent.addCategory(Intent.CATEGORY_HOME);
17943         intent.addCategory(Intent.CATEGORY_DEFAULT);
17944         return intent;
17945     }
17946
17947     private IntentFilter getHomeFilter() {
17948         IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
17949         filter.addCategory(Intent.CATEGORY_HOME);
17950         filter.addCategory(Intent.CATEGORY_DEFAULT);
17951         return filter;
17952     }
17953
17954     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
17955             int userId) {
17956         Intent intent  = getHomeIntent();
17957         List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
17958                 PackageManager.GET_META_DATA, userId);
17959         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
17960                 true, false, false, userId);
17961
17962         allHomeCandidates.clear();
17963         if (list != null) {
17964             for (ResolveInfo ri : list) {
17965                 allHomeCandidates.add(ri);
17966             }
17967         }
17968         return (preferred == null || preferred.activityInfo == null)
17969                 ? null
17970                 : new ComponentName(preferred.activityInfo.packageName,
17971                         preferred.activityInfo.name);
17972     }
17973
17974     @Override
17975     public void setHomeActivity(ComponentName comp, int userId) {
17976         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
17977         getHomeActivitiesAsUser(homeActivities, userId);
17978
17979         boolean found = false;
17980
17981         final int size = homeActivities.size();
17982         final ComponentName[] set = new ComponentName[size];
17983         for (int i = 0; i < size; i++) {
17984             final ResolveInfo candidate = homeActivities.get(i);
17985             final ActivityInfo info = candidate.activityInfo;
17986             final ComponentName activityName = new ComponentName(info.packageName, info.name);
17987             set[i] = activityName;
17988             if (!found && activityName.equals(comp)) {
17989                 found = true;
17990             }
17991         }
17992         if (!found) {
17993             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
17994                     + userId);
17995         }
17996         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
17997                 set, comp, userId);
17998     }
17999
18000     private @Nullable String getSetupWizardPackageName() {
18001         final Intent intent = new Intent(Intent.ACTION_MAIN);
18002         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
18003
18004         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
18005                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
18006                         | MATCH_DISABLED_COMPONENTS,
18007                 UserHandle.myUserId());
18008         if (matches.size() == 1) {
18009             return matches.get(0).getComponentInfo().packageName;
18010         } else {
18011             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
18012                     + ": matches=" + matches);
18013             return null;
18014         }
18015     }
18016
18017     private @Nullable String getStorageManagerPackageName() {
18018         final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
18019
18020         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
18021                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
18022                         | MATCH_DISABLED_COMPONENTS,
18023                 UserHandle.myUserId());
18024         if (matches.size() == 1) {
18025             return matches.get(0).getComponentInfo().packageName;
18026         } else {
18027             Slog.e(TAG, "There should probably be exactly one storage manager; found "
18028                     + matches.size() + ": matches=" + matches);
18029             return null;
18030         }
18031     }
18032
18033     @Override
18034     public void setApplicationEnabledSetting(String appPackageName,
18035             int newState, int flags, int userId, String callingPackage) {
18036         if (!sUserManager.exists(userId)) return;
18037         if (callingPackage == null) {
18038             callingPackage = Integer.toString(Binder.getCallingUid());
18039         }
18040         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
18041     }
18042
18043     @Override
18044     public void setComponentEnabledSetting(ComponentName componentName,
18045             int newState, int flags, int userId) {
18046         if (!sUserManager.exists(userId)) return;
18047         setEnabledSetting(componentName.getPackageName(),
18048                 componentName.getClassName(), newState, flags, userId, null);
18049     }
18050
18051     private void setEnabledSetting(final String packageName, String className, int newState,
18052             final int flags, int userId, String callingPackage) {
18053         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
18054               || newState == COMPONENT_ENABLED_STATE_ENABLED
18055               || newState == COMPONENT_ENABLED_STATE_DISABLED
18056               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
18057               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
18058             throw new IllegalArgumentException("Invalid new component state: "
18059                     + newState);
18060         }
18061         PackageSetting pkgSetting;
18062         final int uid = Binder.getCallingUid();
18063         final int permission;
18064         if (uid == Process.SYSTEM_UID) {
18065             permission = PackageManager.PERMISSION_GRANTED;
18066         } else {
18067             permission = mContext.checkCallingOrSelfPermission(
18068                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
18069         }
18070         enforceCrossUserPermission(uid, userId,
18071                 false /* requireFullPermission */, true /* checkShell */, "set enabled");
18072         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
18073         boolean sendNow = false;
18074         boolean isApp = (className == null);
18075         String componentName = isApp ? packageName : className;
18076         int packageUid = -1;
18077         ArrayList<String> components;
18078
18079         // writer
18080         synchronized (mPackages) {
18081             pkgSetting = mSettings.mPackages.get(packageName);
18082             if (pkgSetting == null) {
18083                 if (className == null) {
18084                     throw new IllegalArgumentException("Unknown package: " + packageName);
18085                 }
18086                 throw new IllegalArgumentException(
18087                         "Unknown component: " + packageName + "/" + className);
18088             }
18089         }
18090
18091         // Limit who can change which apps
18092         if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
18093             // Don't allow apps that don't have permission to modify other apps
18094             if (!allowedByPermission) {
18095                 throw new SecurityException(
18096                         "Permission Denial: attempt to change component state from pid="
18097                         + Binder.getCallingPid()
18098                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
18099             }
18100             // Don't allow changing protected packages.
18101             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
18102                 throw new SecurityException("Cannot disable a protected package: " + packageName);
18103             }
18104         }
18105
18106         synchronized (mPackages) {
18107             if (uid == Process.SHELL_UID) {
18108                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
18109                 int oldState = pkgSetting.getEnabled(userId);
18110                 if (className == null
18111                     &&
18112                     (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
18113                      || oldState == COMPONENT_ENABLED_STATE_DEFAULT
18114                      || oldState == COMPONENT_ENABLED_STATE_ENABLED)
18115                     &&
18116                     (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
18117                      || newState == COMPONENT_ENABLED_STATE_DEFAULT
18118                      || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
18119                     // ok
18120                 } else {
18121                     throw new SecurityException(
18122                             "Shell cannot change component state for " + packageName + "/"
18123                             + className + " to " + newState);
18124                 }
18125             }
18126             if (className == null) {
18127                 // We're dealing with an application/package level state change
18128                 if (pkgSetting.getEnabled(userId) == newState) {
18129                     // Nothing to do
18130                     return;
18131                 }
18132                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
18133                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
18134                     // Don't care about who enables an app.
18135                     callingPackage = null;
18136                 }
18137                 pkgSetting.setEnabled(newState, userId, callingPackage);
18138                 // pkgSetting.pkg.mSetEnabled = newState;
18139             } else {
18140                 // We're dealing with a component level state change
18141                 // First, verify that this is a valid class name.
18142                 PackageParser.Package pkg = pkgSetting.pkg;
18143                 if (pkg == null || !pkg.hasComponentClassName(className)) {
18144                     if (pkg != null &&
18145                             pkg.applicationInfo.targetSdkVersion >=
18146                                     Build.VERSION_CODES.JELLY_BEAN) {
18147                         throw new IllegalArgumentException("Component class " + className
18148                                 + " does not exist in " + packageName);
18149                     } else {
18150                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
18151                                 + className + " does not exist in " + packageName);
18152                     }
18153                 }
18154                 switch (newState) {
18155                 case COMPONENT_ENABLED_STATE_ENABLED:
18156                     if (!pkgSetting.enableComponentLPw(className, userId)) {
18157                         return;
18158                     }
18159                     break;
18160                 case COMPONENT_ENABLED_STATE_DISABLED:
18161                     if (!pkgSetting.disableComponentLPw(className, userId)) {
18162                         return;
18163                     }
18164                     break;
18165                 case COMPONENT_ENABLED_STATE_DEFAULT:
18166                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
18167                         return;
18168                     }
18169                     break;
18170                 default:
18171                     Slog.e(TAG, "Invalid new component state: " + newState);
18172                     return;
18173                 }
18174             }
18175             scheduleWritePackageRestrictionsLocked(userId);
18176             components = mPendingBroadcasts.get(userId, packageName);
18177             final boolean newPackage = components == null;
18178             if (newPackage) {
18179                 components = new ArrayList<String>();
18180             }
18181             if (!components.contains(componentName)) {
18182                 components.add(componentName);
18183             }
18184             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
18185                 sendNow = true;
18186                 // Purge entry from pending broadcast list if another one exists already
18187                 // since we are sending one right away.
18188                 mPendingBroadcasts.remove(userId, packageName);
18189             } else {
18190                 if (newPackage) {
18191                     mPendingBroadcasts.put(userId, packageName, components);
18192                 }
18193                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
18194                     // Schedule a message
18195                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
18196                 }
18197             }
18198         }
18199
18200         long callingId = Binder.clearCallingIdentity();
18201         try {
18202             if (sendNow) {
18203                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
18204                 sendPackageChangedBroadcast(packageName,
18205                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
18206             }
18207         } finally {
18208             Binder.restoreCallingIdentity(callingId);
18209         }
18210     }
18211
18212     @Override
18213     public void flushPackageRestrictionsAsUser(int userId) {
18214         if (!sUserManager.exists(userId)) {
18215             return;
18216         }
18217         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
18218                 false /* checkShell */, "flushPackageRestrictions");
18219         synchronized (mPackages) {
18220             mSettings.writePackageRestrictionsLPr(userId);
18221             mDirtyUsers.remove(userId);
18222             if (mDirtyUsers.isEmpty()) {
18223                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
18224             }
18225         }
18226     }
18227
18228     private void sendPackageChangedBroadcast(String packageName,
18229             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
18230         if (DEBUG_INSTALL)
18231             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
18232                     + componentNames);
18233         Bundle extras = new Bundle(4);
18234         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
18235         String nameList[] = new String[componentNames.size()];
18236         componentNames.toArray(nameList);
18237         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
18238         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
18239         extras.putInt(Intent.EXTRA_UID, packageUid);
18240         // If this is not reporting a change of the overall package, then only send it
18241         // to registered receivers.  We don't want to launch a swath of apps for every
18242         // little component state change.
18243         final int flags = !componentNames.contains(packageName)
18244                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
18245         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
18246                 new int[] {UserHandle.getUserId(packageUid)});
18247     }
18248
18249     @Override
18250     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
18251         if (!sUserManager.exists(userId)) return;
18252         final int uid = Binder.getCallingUid();
18253         final int permission = mContext.checkCallingOrSelfPermission(
18254                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
18255         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
18256         enforceCrossUserPermission(uid, userId,
18257                 true /* requireFullPermission */, true /* checkShell */, "stop package");
18258         // writer
18259         synchronized (mPackages) {
18260             if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
18261                     allowedByPermission, uid, userId)) {
18262                 scheduleWritePackageRestrictionsLocked(userId);
18263             }
18264         }
18265     }
18266
18267     @Override
18268     public String getInstallerPackageName(String packageName) {
18269         // reader
18270         synchronized (mPackages) {
18271             return mSettings.getInstallerPackageNameLPr(packageName);
18272         }
18273     }
18274
18275     public boolean isOrphaned(String packageName) {
18276         // reader
18277         synchronized (mPackages) {
18278             return mSettings.isOrphaned(packageName);
18279         }
18280     }
18281
18282     @Override
18283     public int getApplicationEnabledSetting(String packageName, int userId) {
18284         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
18285         int uid = Binder.getCallingUid();
18286         enforceCrossUserPermission(uid, userId,
18287                 false /* requireFullPermission */, false /* checkShell */, "get enabled");
18288         // reader
18289         synchronized (mPackages) {
18290             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
18291         }
18292     }
18293
18294     @Override
18295     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
18296         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
18297         int uid = Binder.getCallingUid();
18298         enforceCrossUserPermission(uid, userId,
18299                 false /* requireFullPermission */, false /* checkShell */, "get component enabled");
18300         // reader
18301         synchronized (mPackages) {
18302             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
18303         }
18304     }
18305
18306     @Override
18307     public void enterSafeMode() {
18308         enforceSystemOrRoot("Only the system can request entering safe mode");
18309
18310         if (!mSystemReady) {
18311             mSafeMode = true;
18312         }
18313     }
18314
18315     @Override
18316     public void systemReady() {
18317         mSystemReady = true;
18318
18319         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
18320         // disabled after already being started.
18321         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
18322                 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
18323
18324         // Read the compatibilty setting when the system is ready.
18325         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
18326                 mContext.getContentResolver(),
18327                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
18328         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
18329         if (DEBUG_SETTINGS) {
18330             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
18331         }
18332
18333         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
18334
18335         synchronized (mPackages) {
18336             // Verify that all of the preferred activity components actually
18337             // exist.  It is possible for applications to be updated and at
18338             // that point remove a previously declared activity component that
18339             // had been set as a preferred activity.  We try to clean this up
18340             // the next time we encounter that preferred activity, but it is
18341             // possible for the user flow to never be able to return to that
18342             // situation so here we do a sanity check to make sure we haven't
18343             // left any junk around.
18344             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
18345             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18346                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18347                 removed.clear();
18348                 for (PreferredActivity pa : pir.filterSet()) {
18349                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
18350                         removed.add(pa);
18351                     }
18352                 }
18353                 if (removed.size() > 0) {
18354                     for (int r=0; r<removed.size(); r++) {
18355                         PreferredActivity pa = removed.get(r);
18356                         Slog.w(TAG, "Removing dangling preferred activity: "
18357                                 + pa.mPref.mComponent);
18358                         pir.removeFilter(pa);
18359                     }
18360                     mSettings.writePackageRestrictionsLPr(
18361                             mSettings.mPreferredActivities.keyAt(i));
18362                 }
18363             }
18364
18365             for (int userId : UserManagerService.getInstance().getUserIds()) {
18366                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
18367                     grantPermissionsUserIds = ArrayUtils.appendInt(
18368                             grantPermissionsUserIds, userId);
18369                 }
18370             }
18371         }
18372         sUserManager.systemReady();
18373
18374         // If we upgraded grant all default permissions before kicking off.
18375         for (int userId : grantPermissionsUserIds) {
18376             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
18377         }
18378
18379         // If we did not grant default permissions, we preload from this the
18380         // default permission exceptions lazily to ensure we don't hit the
18381         // disk on a new user creation.
18382         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
18383             mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
18384         }
18385
18386         // Kick off any messages waiting for system ready
18387         if (mPostSystemReadyMessages != null) {
18388             for (Message msg : mPostSystemReadyMessages) {
18389                 msg.sendToTarget();
18390             }
18391             mPostSystemReadyMessages = null;
18392         }
18393
18394         // Watch for external volumes that come and go over time
18395         final StorageManager storage = mContext.getSystemService(StorageManager.class);
18396         storage.registerListener(mStorageListener);
18397
18398         mInstallerService.systemReady();
18399         mPackageDexOptimizer.systemReady();
18400
18401         MountServiceInternal mountServiceInternal = LocalServices.getService(
18402                 MountServiceInternal.class);
18403         mountServiceInternal.addExternalStoragePolicy(
18404                 new MountServiceInternal.ExternalStorageMountPolicy() {
18405             @Override
18406             public int getMountMode(int uid, String packageName) {
18407                 if (Process.isIsolated(uid)) {
18408                     return Zygote.MOUNT_EXTERNAL_NONE;
18409                 }
18410                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
18411                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
18412                 }
18413                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
18414                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
18415                 }
18416                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
18417                     return Zygote.MOUNT_EXTERNAL_READ;
18418                 }
18419                 return Zygote.MOUNT_EXTERNAL_WRITE;
18420             }
18421
18422             @Override
18423             public boolean hasExternalStorage(int uid, String packageName) {
18424                 return true;
18425             }
18426         });
18427
18428         // Now that we're mostly running, clean up stale users and apps
18429         reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
18430         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
18431     }
18432
18433     @Override
18434     public boolean isSafeMode() {
18435         return mSafeMode;
18436     }
18437
18438     @Override
18439     public boolean hasSystemUidErrors() {
18440         return mHasSystemUidErrors;
18441     }
18442
18443     static String arrayToString(int[] array) {
18444         StringBuffer buf = new StringBuffer(128);
18445         buf.append('[');
18446         if (array != null) {
18447             for (int i=0; i<array.length; i++) {
18448                 if (i > 0) buf.append(", ");
18449                 buf.append(array[i]);
18450             }
18451         }
18452         buf.append(']');
18453         return buf.toString();
18454     }
18455
18456     static class DumpState {
18457         public static final int DUMP_LIBS = 1 << 0;
18458         public static final int DUMP_FEATURES = 1 << 1;
18459         public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
18460         public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
18461         public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
18462         public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
18463         public static final int DUMP_PERMISSIONS = 1 << 6;
18464         public static final int DUMP_PACKAGES = 1 << 7;
18465         public static final int DUMP_SHARED_USERS = 1 << 8;
18466         public static final int DUMP_MESSAGES = 1 << 9;
18467         public static final int DUMP_PROVIDERS = 1 << 10;
18468         public static final int DUMP_VERIFIERS = 1 << 11;
18469         public static final int DUMP_PREFERRED = 1 << 12;
18470         public static final int DUMP_PREFERRED_XML = 1 << 13;
18471         public static final int DUMP_KEYSETS = 1 << 14;
18472         public static final int DUMP_VERSION = 1 << 15;
18473         public static final int DUMP_INSTALLS = 1 << 16;
18474         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
18475         public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
18476         public static final int DUMP_FROZEN = 1 << 19;
18477         public static final int DUMP_DEXOPT = 1 << 20;
18478         public static final int DUMP_COMPILER_STATS = 1 << 21;
18479
18480         public static final int OPTION_SHOW_FILTERS = 1 << 0;
18481
18482         private int mTypes;
18483
18484         private int mOptions;
18485
18486         private boolean mTitlePrinted;
18487
18488         private SharedUserSetting mSharedUser;
18489
18490         public boolean isDumping(int type) {
18491             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
18492                 return true;
18493             }
18494
18495             return (mTypes & type) != 0;
18496         }
18497
18498         public void setDump(int type) {
18499             mTypes |= type;
18500         }
18501
18502         public boolean isOptionEnabled(int option) {
18503             return (mOptions & option) != 0;
18504         }
18505
18506         public void setOptionEnabled(int option) {
18507             mOptions |= option;
18508         }
18509
18510         public boolean onTitlePrinted() {
18511             final boolean printed = mTitlePrinted;
18512             mTitlePrinted = true;
18513             return printed;
18514         }
18515
18516         public boolean getTitlePrinted() {
18517             return mTitlePrinted;
18518         }
18519
18520         public void setTitlePrinted(boolean enabled) {
18521             mTitlePrinted = enabled;
18522         }
18523
18524         public SharedUserSetting getSharedUser() {
18525             return mSharedUser;
18526         }
18527
18528         public void setSharedUser(SharedUserSetting user) {
18529             mSharedUser = user;
18530         }
18531     }
18532
18533     @Override
18534     public void onShellCommand(FileDescriptor in, FileDescriptor out,
18535             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
18536         (new PackageManagerShellCommand(this)).exec(
18537                 this, in, out, err, args, resultReceiver);
18538     }
18539
18540     @Override
18541     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
18542         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
18543                 != PackageManager.PERMISSION_GRANTED) {
18544             pw.println("Permission Denial: can't dump ActivityManager from from pid="
18545                     + Binder.getCallingPid()
18546                     + ", uid=" + Binder.getCallingUid()
18547                     + " without permission "
18548                     + android.Manifest.permission.DUMP);
18549             return;
18550         }
18551
18552         DumpState dumpState = new DumpState();
18553         boolean fullPreferred = false;
18554         boolean checkin = false;
18555
18556         String packageName = null;
18557         ArraySet<String> permissionNames = null;
18558
18559         int opti = 0;
18560         while (opti < args.length) {
18561             String opt = args[opti];
18562             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18563                 break;
18564             }
18565             opti++;
18566
18567             if ("-a".equals(opt)) {
18568                 // Right now we only know how to print all.
18569             } else if ("-h".equals(opt)) {
18570                 pw.println("Package manager dump options:");
18571                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
18572                 pw.println("    --checkin: dump for a checkin");
18573                 pw.println("    -f: print details of intent filters");
18574                 pw.println("    -h: print this help");
18575                 pw.println("  cmd may be one of:");
18576                 pw.println("    l[ibraries]: list known shared libraries");
18577                 pw.println("    f[eatures]: list device features");
18578                 pw.println("    k[eysets]: print known keysets");
18579                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
18580                 pw.println("    perm[issions]: dump permissions");
18581                 pw.println("    permission [name ...]: dump declaration and use of given permission");
18582                 pw.println("    pref[erred]: print preferred package settings");
18583                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
18584                 pw.println("    prov[iders]: dump content providers");
18585                 pw.println("    p[ackages]: dump installed packages");
18586                 pw.println("    s[hared-users]: dump shared user IDs");
18587                 pw.println("    m[essages]: print collected runtime messages");
18588                 pw.println("    v[erifiers]: print package verifier info");
18589                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
18590                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
18591                 pw.println("    version: print database version info");
18592                 pw.println("    write: write current settings now");
18593                 pw.println("    installs: details about install sessions");
18594                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
18595                 pw.println("    dexopt: dump dexopt state");
18596                 pw.println("    compiler-stats: dump compiler statistics");
18597                 pw.println("    <package.name>: info about given package");
18598                 return;
18599             } else if ("--checkin".equals(opt)) {
18600                 checkin = true;
18601             } else if ("-f".equals(opt)) {
18602                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18603             } else {
18604                 pw.println("Unknown argument: " + opt + "; use -h for help");
18605             }
18606         }
18607
18608         // Is the caller requesting to dump a particular piece of data?
18609         if (opti < args.length) {
18610             String cmd = args[opti];
18611             opti++;
18612             // Is this a package name?
18613             if ("android".equals(cmd) || cmd.contains(".")) {
18614                 packageName = cmd;
18615                 // When dumping a single package, we always dump all of its
18616                 // filter information since the amount of data will be reasonable.
18617                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18618             } else if ("check-permission".equals(cmd)) {
18619                 if (opti >= args.length) {
18620                     pw.println("Error: check-permission missing permission argument");
18621                     return;
18622                 }
18623                 String perm = args[opti];
18624                 opti++;
18625                 if (opti >= args.length) {
18626                     pw.println("Error: check-permission missing package argument");
18627                     return;
18628                 }
18629                 String pkg = args[opti];
18630                 opti++;
18631                 int user = UserHandle.getUserId(Binder.getCallingUid());
18632                 if (opti < args.length) {
18633                     try {
18634                         user = Integer.parseInt(args[opti]);
18635                     } catch (NumberFormatException e) {
18636                         pw.println("Error: check-permission user argument is not a number: "
18637                                 + args[opti]);
18638                         return;
18639                     }
18640                 }
18641                 pw.println(checkPermission(perm, pkg, user));
18642                 return;
18643             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
18644                 dumpState.setDump(DumpState.DUMP_LIBS);
18645             } else if ("f".equals(cmd) || "features".equals(cmd)) {
18646                 dumpState.setDump(DumpState.DUMP_FEATURES);
18647             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
18648                 if (opti >= args.length) {
18649                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
18650                             | DumpState.DUMP_SERVICE_RESOLVERS
18651                             | DumpState.DUMP_RECEIVER_RESOLVERS
18652                             | DumpState.DUMP_CONTENT_RESOLVERS);
18653                 } else {
18654                     while (opti < args.length) {
18655                         String name = args[opti];
18656                         if ("a".equals(name) || "activity".equals(name)) {
18657                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
18658                         } else if ("s".equals(name) || "service".equals(name)) {
18659                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
18660                         } else if ("r".equals(name) || "receiver".equals(name)) {
18661                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
18662                         } else if ("c".equals(name) || "content".equals(name)) {
18663                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
18664                         } else {
18665                             pw.println("Error: unknown resolver table type: " + name);
18666                             return;
18667                         }
18668                         opti++;
18669                     }
18670                 }
18671             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
18672                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
18673             } else if ("permission".equals(cmd)) {
18674                 if (opti >= args.length) {
18675                     pw.println("Error: permission requires permission name");
18676                     return;
18677                 }
18678                 permissionNames = new ArraySet<>();
18679                 while (opti < args.length) {
18680                     permissionNames.add(args[opti]);
18681                     opti++;
18682                 }
18683                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
18684                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
18685             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
18686                 dumpState.setDump(DumpState.DUMP_PREFERRED);
18687             } else if ("preferred-xml".equals(cmd)) {
18688                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
18689                 if (opti < args.length && "--full".equals(args[opti])) {
18690                     fullPreferred = true;
18691                     opti++;
18692                 }
18693             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
18694                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
18695             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
18696                 dumpState.setDump(DumpState.DUMP_PACKAGES);
18697             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
18698                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
18699             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
18700                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
18701             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
18702                 dumpState.setDump(DumpState.DUMP_MESSAGES);
18703             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
18704                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
18705             } else if ("i".equals(cmd) || "ifv".equals(cmd)
18706                     || "intent-filter-verifiers".equals(cmd)) {
18707                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
18708             } else if ("version".equals(cmd)) {
18709                 dumpState.setDump(DumpState.DUMP_VERSION);
18710             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
18711                 dumpState.setDump(DumpState.DUMP_KEYSETS);
18712             } else if ("installs".equals(cmd)) {
18713                 dumpState.setDump(DumpState.DUMP_INSTALLS);
18714             } else if ("frozen".equals(cmd)) {
18715                 dumpState.setDump(DumpState.DUMP_FROZEN);
18716             } else if ("dexopt".equals(cmd)) {
18717                 dumpState.setDump(DumpState.DUMP_DEXOPT);
18718             } else if ("compiler-stats".equals(cmd)) {
18719                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
18720             } else if ("write".equals(cmd)) {
18721                 synchronized (mPackages) {
18722                     mSettings.writeLPr();
18723                     pw.println("Settings written.");
18724                     return;
18725                 }
18726             }
18727         }
18728
18729         if (checkin) {
18730             pw.println("vers,1");
18731         }
18732
18733         // reader
18734         synchronized (mPackages) {
18735             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
18736                 if (!checkin) {
18737                     if (dumpState.onTitlePrinted())
18738                         pw.println();
18739                     pw.println("Database versions:");
18740                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
18741                 }
18742             }
18743
18744             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
18745                 if (!checkin) {
18746                     if (dumpState.onTitlePrinted())
18747                         pw.println();
18748                     pw.println("Verifiers:");
18749                     pw.print("  Required: ");
18750                     pw.print(mRequiredVerifierPackage);
18751                     pw.print(" (uid=");
18752                     pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18753                             UserHandle.USER_SYSTEM));
18754                     pw.println(")");
18755                 } else if (mRequiredVerifierPackage != null) {
18756                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
18757                     pw.print(",");
18758                     pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18759                             UserHandle.USER_SYSTEM));
18760                 }
18761             }
18762
18763             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
18764                     packageName == null) {
18765                 if (mIntentFilterVerifierComponent != null) {
18766                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
18767                     if (!checkin) {
18768                         if (dumpState.onTitlePrinted())
18769                             pw.println();
18770                         pw.println("Intent Filter Verifier:");
18771                         pw.print("  Using: ");
18772                         pw.print(verifierPackageName);
18773                         pw.print(" (uid=");
18774                         pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18775                                 UserHandle.USER_SYSTEM));
18776                         pw.println(")");
18777                     } else if (verifierPackageName != null) {
18778                         pw.print("ifv,"); pw.print(verifierPackageName);
18779                         pw.print(",");
18780                         pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18781                                 UserHandle.USER_SYSTEM));
18782                     }
18783                 } else {
18784                     pw.println();
18785                     pw.println("No Intent Filter Verifier available!");
18786                 }
18787             }
18788
18789             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
18790                 boolean printedHeader = false;
18791                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
18792                 while (it.hasNext()) {
18793                     String name = it.next();
18794                     SharedLibraryEntry ent = mSharedLibraries.get(name);
18795                     if (!checkin) {
18796                         if (!printedHeader) {
18797                             if (dumpState.onTitlePrinted())
18798                                 pw.println();
18799                             pw.println("Libraries:");
18800                             printedHeader = true;
18801                         }
18802                         pw.print("  ");
18803                     } else {
18804                         pw.print("lib,");
18805                     }
18806                     pw.print(name);
18807                     if (!checkin) {
18808                         pw.print(" -> ");
18809                     }
18810                     if (ent.path != null) {
18811                         if (!checkin) {
18812                             pw.print("(jar) ");
18813                             pw.print(ent.path);
18814                         } else {
18815                             pw.print(",jar,");
18816                             pw.print(ent.path);
18817                         }
18818                     } else {
18819                         if (!checkin) {
18820                             pw.print("(apk) ");
18821                             pw.print(ent.apk);
18822                         } else {
18823                             pw.print(",apk,");
18824                             pw.print(ent.apk);
18825                         }
18826                     }
18827                     pw.println();
18828                 }
18829             }
18830
18831             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
18832                 if (dumpState.onTitlePrinted())
18833                     pw.println();
18834                 if (!checkin) {
18835                     pw.println("Features:");
18836                 }
18837
18838                 for (FeatureInfo feat : mAvailableFeatures.values()) {
18839                     if (checkin) {
18840                         pw.print("feat,");
18841                         pw.print(feat.name);
18842                         pw.print(",");
18843                         pw.println(feat.version);
18844                     } else {
18845                         pw.print("  ");
18846                         pw.print(feat.name);
18847                         if (feat.version > 0) {
18848                             pw.print(" version=");
18849                             pw.print(feat.version);
18850                         }
18851                         pw.println();
18852                     }
18853                 }
18854             }
18855
18856             if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
18857                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
18858                         : "Activity Resolver Table:", "  ", packageName,
18859                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18860                     dumpState.setTitlePrinted(true);
18861                 }
18862             }
18863             if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
18864                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
18865                         : "Receiver Resolver Table:", "  ", packageName,
18866                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18867                     dumpState.setTitlePrinted(true);
18868                 }
18869             }
18870             if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
18871                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
18872                         : "Service Resolver Table:", "  ", packageName,
18873                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18874                     dumpState.setTitlePrinted(true);
18875                 }
18876             }
18877             if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
18878                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
18879                         : "Provider Resolver Table:", "  ", packageName,
18880                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18881                     dumpState.setTitlePrinted(true);
18882                 }
18883             }
18884
18885             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
18886                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18887                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18888                     int user = mSettings.mPreferredActivities.keyAt(i);
18889                     if (pir.dump(pw,
18890                             dumpState.getTitlePrinted()
18891                                 ? "\nPreferred Activities User " + user + ":"
18892                                 : "Preferred Activities User " + user + ":", "  ",
18893                             packageName, true, false)) {
18894                         dumpState.setTitlePrinted(true);
18895                     }
18896                 }
18897             }
18898
18899             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
18900                 pw.flush();
18901                 FileOutputStream fout = new FileOutputStream(fd);
18902                 BufferedOutputStream str = new BufferedOutputStream(fout);
18903                 XmlSerializer serializer = new FastXmlSerializer();
18904                 try {
18905                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
18906                     serializer.startDocument(null, true);
18907                     serializer.setFeature(
18908                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
18909                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
18910                     serializer.endDocument();
18911                     serializer.flush();
18912                 } catch (IllegalArgumentException e) {
18913                     pw.println("Failed writing: " + e);
18914                 } catch (IllegalStateException e) {
18915                     pw.println("Failed writing: " + e);
18916                 } catch (IOException e) {
18917                     pw.println("Failed writing: " + e);
18918                 }
18919             }
18920
18921             if (!checkin
18922                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
18923                     && packageName == null) {
18924                 pw.println();
18925                 int count = mSettings.mPackages.size();
18926                 if (count == 0) {
18927                     pw.println("No applications!");
18928                     pw.println();
18929                 } else {
18930                     final String prefix = "  ";
18931                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
18932                     if (allPackageSettings.size() == 0) {
18933                         pw.println("No domain preferred apps!");
18934                         pw.println();
18935                     } else {
18936                         pw.println("App verification status:");
18937                         pw.println();
18938                         count = 0;
18939                         for (PackageSetting ps : allPackageSettings) {
18940                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
18941                             if (ivi == null || ivi.getPackageName() == null) continue;
18942                             pw.println(prefix + "Package: " + ivi.getPackageName());
18943                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
18944                             pw.println(prefix + "Status:  " + ivi.getStatusString());
18945                             pw.println();
18946                             count++;
18947                         }
18948                         if (count == 0) {
18949                             pw.println(prefix + "No app verification established.");
18950                             pw.println();
18951                         }
18952                         for (int userId : sUserManager.getUserIds()) {
18953                             pw.println("App linkages for user " + userId + ":");
18954                             pw.println();
18955                             count = 0;
18956                             for (PackageSetting ps : allPackageSettings) {
18957                                 final long status = ps.getDomainVerificationStatusForUser(userId);
18958                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
18959                                     continue;
18960                                 }
18961                                 pw.println(prefix + "Package: " + ps.name);
18962                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
18963                                 String statusStr = IntentFilterVerificationInfo.
18964                                         getStatusStringFromValue(status);
18965                                 pw.println(prefix + "Status:  " + statusStr);
18966                                 pw.println();
18967                                 count++;
18968                             }
18969                             if (count == 0) {
18970                                 pw.println(prefix + "No configured app linkages.");
18971                                 pw.println();
18972                             }
18973                         }
18974                     }
18975                 }
18976             }
18977
18978             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
18979                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
18980                 if (packageName == null && permissionNames == null) {
18981                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
18982                         if (iperm == 0) {
18983                             if (dumpState.onTitlePrinted())
18984                                 pw.println();
18985                             pw.println("AppOp Permissions:");
18986                         }
18987                         pw.print("  AppOp Permission ");
18988                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
18989                         pw.println(":");
18990                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
18991                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
18992                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
18993                         }
18994                     }
18995                 }
18996             }
18997
18998             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
18999                 boolean printedSomething = false;
19000                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
19001                     if (packageName != null && !packageName.equals(p.info.packageName)) {
19002                         continue;
19003                     }
19004                     if (!printedSomething) {
19005                         if (dumpState.onTitlePrinted())
19006                             pw.println();
19007                         pw.println("Registered ContentProviders:");
19008                         printedSomething = true;
19009                     }
19010                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
19011                     pw.print("    "); pw.println(p.toString());
19012                 }
19013                 printedSomething = false;
19014                 for (Map.Entry<String, PackageParser.Provider> entry :
19015                         mProvidersByAuthority.entrySet()) {
19016                     PackageParser.Provider p = entry.getValue();
19017                     if (packageName != null && !packageName.equals(p.info.packageName)) {
19018                         continue;
19019                     }
19020                     if (!printedSomething) {
19021                         if (dumpState.onTitlePrinted())
19022                             pw.println();
19023                         pw.println("ContentProvider Authorities:");
19024                         printedSomething = true;
19025                     }
19026                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
19027                     pw.print("    "); pw.println(p.toString());
19028                     if (p.info != null && p.info.applicationInfo != null) {
19029                         final String appInfo = p.info.applicationInfo.toString();
19030                         pw.print("      applicationInfo="); pw.println(appInfo);
19031                     }
19032                 }
19033             }
19034
19035             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
19036                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
19037             }
19038
19039             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
19040                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
19041             }
19042
19043             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
19044                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
19045             }
19046
19047             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
19048                 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
19049             }
19050
19051             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
19052                 // XXX should handle packageName != null by dumping only install data that
19053                 // the given package is involved with.
19054                 if (dumpState.onTitlePrinted()) pw.println();
19055                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
19056             }
19057
19058             if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
19059                 // XXX should handle packageName != null by dumping only install data that
19060                 // the given package is involved with.
19061                 if (dumpState.onTitlePrinted()) pw.println();
19062
19063                 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
19064                 ipw.println();
19065                 ipw.println("Frozen packages:");
19066                 ipw.increaseIndent();
19067                 if (mFrozenPackages.size() == 0) {
19068                     ipw.println("(none)");
19069                 } else {
19070                     for (int i = 0; i < mFrozenPackages.size(); i++) {
19071                         ipw.println(mFrozenPackages.valueAt(i));
19072                     }
19073                 }
19074                 ipw.decreaseIndent();
19075             }
19076
19077             if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
19078                 if (dumpState.onTitlePrinted()) pw.println();
19079                 dumpDexoptStateLPr(pw, packageName);
19080             }
19081
19082             if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
19083                 if (dumpState.onTitlePrinted()) pw.println();
19084                 dumpCompilerStatsLPr(pw, packageName);
19085             }
19086
19087             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
19088                 if (dumpState.onTitlePrinted()) pw.println();
19089                 mSettings.dumpReadMessagesLPr(pw, dumpState);
19090
19091                 pw.println();
19092                 pw.println("Package warning messages:");
19093                 BufferedReader in = null;
19094                 String line = null;
19095                 try {
19096                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
19097                     while ((line = in.readLine()) != null) {
19098                         if (line.contains("ignored: updated version")) continue;
19099                         pw.println(line);
19100                     }
19101                 } catch (IOException ignored) {
19102                 } finally {
19103                     IoUtils.closeQuietly(in);
19104                 }
19105             }
19106
19107             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
19108                 BufferedReader in = null;
19109                 String line = null;
19110                 try {
19111                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
19112                     while ((line = in.readLine()) != null) {
19113                         if (line.contains("ignored: updated version")) continue;
19114                         pw.print("msg,");
19115                         pw.println(line);
19116                     }
19117                 } catch (IOException ignored) {
19118                 } finally {
19119                     IoUtils.closeQuietly(in);
19120                 }
19121             }
19122         }
19123     }
19124
19125     private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
19126         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
19127         ipw.println();
19128         ipw.println("Dexopt state:");
19129         ipw.increaseIndent();
19130         Collection<PackageParser.Package> packages = null;
19131         if (packageName != null) {
19132             PackageParser.Package targetPackage = mPackages.get(packageName);
19133             if (targetPackage != null) {
19134                 packages = Collections.singletonList(targetPackage);
19135             } else {
19136                 ipw.println("Unable to find package: " + packageName);
19137                 return;
19138             }
19139         } else {
19140             packages = mPackages.values();
19141         }
19142
19143         for (PackageParser.Package pkg : packages) {
19144             ipw.println("[" + pkg.packageName + "]");
19145             ipw.increaseIndent();
19146             mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
19147             ipw.decreaseIndent();
19148         }
19149     }
19150
19151     private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
19152         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
19153         ipw.println();
19154         ipw.println("Compiler stats:");
19155         ipw.increaseIndent();
19156         Collection<PackageParser.Package> packages = null;
19157         if (packageName != null) {
19158             PackageParser.Package targetPackage = mPackages.get(packageName);
19159             if (targetPackage != null) {
19160                 packages = Collections.singletonList(targetPackage);
19161             } else {
19162                 ipw.println("Unable to find package: " + packageName);
19163                 return;
19164             }
19165         } else {
19166             packages = mPackages.values();
19167         }
19168
19169         for (PackageParser.Package pkg : packages) {
19170             ipw.println("[" + pkg.packageName + "]");
19171             ipw.increaseIndent();
19172
19173             CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
19174             if (stats == null) {
19175                 ipw.println("(No recorded stats)");
19176             } else {
19177                 stats.dump(ipw);
19178             }
19179             ipw.decreaseIndent();
19180         }
19181     }
19182
19183     private String dumpDomainString(String packageName) {
19184         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
19185                 .getList();
19186         List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
19187
19188         ArraySet<String> result = new ArraySet<>();
19189         if (iviList.size() > 0) {
19190             for (IntentFilterVerificationInfo ivi : iviList) {
19191                 for (String host : ivi.getDomains()) {
19192                     result.add(host);
19193                 }
19194             }
19195         }
19196         if (filters != null && filters.size() > 0) {
19197             for (IntentFilter filter : filters) {
19198                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
19199                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
19200                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
19201                     result.addAll(filter.getHostsList());
19202                 }
19203             }
19204         }
19205
19206         StringBuilder sb = new StringBuilder(result.size() * 16);
19207         for (String domain : result) {
19208             if (sb.length() > 0) sb.append(" ");
19209             sb.append(domain);
19210         }
19211         return sb.toString();
19212     }
19213
19214     // ------- apps on sdcard specific code -------
19215     static final boolean DEBUG_SD_INSTALL = false;
19216
19217     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
19218
19219     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
19220
19221     private boolean mMediaMounted = false;
19222
19223     static String getEncryptKey() {
19224         try {
19225             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
19226                     SD_ENCRYPTION_KEYSTORE_NAME);
19227             if (sdEncKey == null) {
19228                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
19229                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
19230                 if (sdEncKey == null) {
19231                     Slog.e(TAG, "Failed to create encryption keys");
19232                     return null;
19233                 }
19234             }
19235             return sdEncKey;
19236         } catch (NoSuchAlgorithmException nsae) {
19237             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
19238             return null;
19239         } catch (IOException ioe) {
19240             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
19241             return null;
19242         }
19243     }
19244
19245     /*
19246      * Update media status on PackageManager.
19247      */
19248     @Override
19249     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
19250         int callingUid = Binder.getCallingUid();
19251         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
19252             throw new SecurityException("Media status can only be updated by the system");
19253         }
19254         // reader; this apparently protects mMediaMounted, but should probably
19255         // be a different lock in that case.
19256         synchronized (mPackages) {
19257             Log.i(TAG, "Updating external media status from "
19258                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
19259                     + (mediaStatus ? "mounted" : "unmounted"));
19260             if (DEBUG_SD_INSTALL)
19261                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
19262                         + ", mMediaMounted=" + mMediaMounted);
19263             if (mediaStatus == mMediaMounted) {
19264                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
19265                         : 0, -1);
19266                 mHandler.sendMessage(msg);
19267                 return;
19268             }
19269             mMediaMounted = mediaStatus;
19270         }
19271         // Queue up an async operation since the package installation may take a
19272         // little while.
19273         mHandler.post(new Runnable() {
19274             public void run() {
19275                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
19276             }
19277         });
19278     }
19279
19280     /**
19281      * Called by MountService when the initial ASECs to scan are available.
19282      * Should block until all the ASEC containers are finished being scanned.
19283      */
19284     public void scanAvailableAsecs() {
19285         updateExternalMediaStatusInner(true, false, false);
19286     }
19287
19288     /*
19289      * Collect information of applications on external media, map them against
19290      * existing containers and update information based on current mount status.
19291      * Please note that we always have to report status if reportStatus has been
19292      * set to true especially when unloading packages.
19293      */
19294     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
19295             boolean externalStorage) {
19296         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
19297         int[] uidArr = EmptyArray.INT;
19298
19299         final String[] list = PackageHelper.getSecureContainerList();
19300         if (ArrayUtils.isEmpty(list)) {
19301             Log.i(TAG, "No secure containers found");
19302         } else {
19303             // Process list of secure containers and categorize them
19304             // as active or stale based on their package internal state.
19305
19306             // reader
19307             synchronized (mPackages) {
19308                 for (String cid : list) {
19309                     // Leave stages untouched for now; installer service owns them
19310                     if (PackageInstallerService.isStageName(cid)) continue;
19311
19312                     if (DEBUG_SD_INSTALL)
19313                         Log.i(TAG, "Processing container " + cid);
19314                     String pkgName = getAsecPackageName(cid);
19315                     if (pkgName == null) {
19316                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
19317                         continue;
19318                     }
19319                     if (DEBUG_SD_INSTALL)
19320                         Log.i(TAG, "Looking for pkg : " + pkgName);
19321
19322                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
19323                     if (ps == null) {
19324                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
19325                         continue;
19326                     }
19327
19328                     /*
19329                      * Skip packages that are not external if we're unmounting
19330                      * external storage.
19331                      */
19332                     if (externalStorage && !isMounted && !isExternal(ps)) {
19333                         continue;
19334                     }
19335
19336                     final AsecInstallArgs args = new AsecInstallArgs(cid,
19337                             getAppDexInstructionSets(ps), ps.isForwardLocked());
19338                     // The package status is changed only if the code path
19339                     // matches between settings and the container id.
19340                     if (ps.codePathString != null
19341                             && ps.codePathString.startsWith(args.getCodePath())) {
19342                         if (DEBUG_SD_INSTALL) {
19343                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
19344                                     + " at code path: " + ps.codePathString);
19345                         }
19346
19347                         // We do have a valid package installed on sdcard
19348                         processCids.put(args, ps.codePathString);
19349                         final int uid = ps.appId;
19350                         if (uid != -1) {
19351                             uidArr = ArrayUtils.appendInt(uidArr, uid);
19352                         }
19353                     } else {
19354                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
19355                                 + ps.codePathString);
19356                     }
19357                 }
19358             }
19359
19360             Arrays.sort(uidArr);
19361         }
19362
19363         // Process packages with valid entries.
19364         if (isMounted) {
19365             if (DEBUG_SD_INSTALL)
19366                 Log.i(TAG, "Loading packages");
19367             loadMediaPackages(processCids, uidArr, externalStorage);
19368             startCleaningPackages();
19369             mInstallerService.onSecureContainersAvailable();
19370         } else {
19371             if (DEBUG_SD_INSTALL)
19372                 Log.i(TAG, "Unloading packages");
19373             unloadMediaPackages(processCids, uidArr, reportStatus);
19374         }
19375     }
19376
19377     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19378             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
19379         final int size = infos.size();
19380         final String[] packageNames = new String[size];
19381         final int[] packageUids = new int[size];
19382         for (int i = 0; i < size; i++) {
19383             final ApplicationInfo info = infos.get(i);
19384             packageNames[i] = info.packageName;
19385             packageUids[i] = info.uid;
19386         }
19387         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
19388                 finishedReceiver);
19389     }
19390
19391     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19392             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
19393         sendResourcesChangedBroadcast(mediaStatus, replacing,
19394                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
19395     }
19396
19397     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19398             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
19399         int size = pkgList.length;
19400         if (size > 0) {
19401             // Send broadcasts here
19402             Bundle extras = new Bundle();
19403             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
19404             if (uidArr != null) {
19405                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
19406             }
19407             if (replacing) {
19408                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
19409             }
19410             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
19411                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
19412             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
19413         }
19414     }
19415
19416    /*
19417      * Look at potentially valid container ids from processCids If package
19418      * information doesn't match the one on record or package scanning fails,
19419      * the cid is added to list of removeCids. We currently don't delete stale
19420      * containers.
19421      */
19422     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
19423             boolean externalStorage) {
19424         ArrayList<String> pkgList = new ArrayList<String>();
19425         Set<AsecInstallArgs> keys = processCids.keySet();
19426
19427         for (AsecInstallArgs args : keys) {
19428             String codePath = processCids.get(args);
19429             if (DEBUG_SD_INSTALL)
19430                 Log.i(TAG, "Loading container : " + args.cid);
19431             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
19432             try {
19433                 // Make sure there are no container errors first.
19434                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
19435                     Slog.e(TAG, "Failed to mount cid : " + args.cid
19436                             + " when installing from sdcard");
19437                     continue;
19438                 }
19439                 // Check code path here.
19440                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
19441                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
19442                             + " does not match one in settings " + codePath);
19443                     continue;
19444                 }
19445                 // Parse package
19446                 int parseFlags = mDefParseFlags;
19447                 if (args.isExternalAsec()) {
19448                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
19449                 }
19450                 if (args.isFwdLocked()) {
19451                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
19452                 }
19453
19454                 synchronized (mInstallLock) {
19455                     PackageParser.Package pkg = null;
19456                     try {
19457                         // Sadly we don't know the package name yet to freeze it
19458                         pkg = scanPackageTracedLI(new File(codePath), parseFlags,
19459                                 SCAN_IGNORE_FROZEN, 0, null);
19460                     } catch (PackageManagerException e) {
19461                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
19462                     }
19463                     // Scan the package
19464                     if (pkg != null) {
19465                         /*
19466                          * TODO why is the lock being held? doPostInstall is
19467                          * called in other places without the lock. This needs
19468                          * to be straightened out.
19469                          */
19470                         // writer
19471                         synchronized (mPackages) {
19472                             retCode = PackageManager.INSTALL_SUCCEEDED;
19473                             pkgList.add(pkg.packageName);
19474                             // Post process args
19475                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
19476                                     pkg.applicationInfo.uid);
19477                         }
19478                     } else {
19479                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
19480                     }
19481                 }
19482
19483             } finally {
19484                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
19485                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
19486                 }
19487             }
19488         }
19489         // writer
19490         synchronized (mPackages) {
19491             // If the platform SDK has changed since the last time we booted,
19492             // we need to re-grant app permission to catch any new ones that
19493             // appear. This is really a hack, and means that apps can in some
19494             // cases get permissions that the user didn't initially explicitly
19495             // allow... it would be nice to have some better way to handle
19496             // this situation.
19497             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
19498                     : mSettings.getInternalVersion();
19499             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
19500                     : StorageManager.UUID_PRIVATE_INTERNAL;
19501
19502             int updateFlags = UPDATE_PERMISSIONS_ALL;
19503             if (ver.sdkVersion != mSdkVersion) {
19504                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19505                         + mSdkVersion + "; regranting permissions for external");
19506                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19507             }
19508             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19509
19510             // Yay, everything is now upgraded
19511             ver.forceCurrent();
19512
19513             // can downgrade to reader
19514             // Persist settings
19515             mSettings.writeLPr();
19516         }
19517         // Send a broadcast to let everyone know we are done processing
19518         if (pkgList.size() > 0) {
19519             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
19520         }
19521     }
19522
19523    /*
19524      * Utility method to unload a list of specified containers
19525      */
19526     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
19527         // Just unmount all valid containers.
19528         for (AsecInstallArgs arg : cidArgs) {
19529             synchronized (mInstallLock) {
19530                 arg.doPostDeleteLI(false);
19531            }
19532        }
19533    }
19534
19535     /*
19536      * Unload packages mounted on external media. This involves deleting package
19537      * data from internal structures, sending broadcasts about disabled packages,
19538      * gc'ing to free up references, unmounting all secure containers
19539      * corresponding to packages on external media, and posting a
19540      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
19541      * that we always have to post this message if status has been requested no
19542      * matter what.
19543      */
19544     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
19545             final boolean reportStatus) {
19546         if (DEBUG_SD_INSTALL)
19547             Log.i(TAG, "unloading media packages");
19548         ArrayList<String> pkgList = new ArrayList<String>();
19549         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
19550         final Set<AsecInstallArgs> keys = processCids.keySet();
19551         for (AsecInstallArgs args : keys) {
19552             String pkgName = args.getPackageName();
19553             if (DEBUG_SD_INSTALL)
19554                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
19555             // Delete package internally
19556             PackageRemovedInfo outInfo = new PackageRemovedInfo();
19557             synchronized (mInstallLock) {
19558                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19559                 final boolean res;
19560                 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
19561                         "unloadMediaPackages")) {
19562                     res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
19563                             null);
19564                 }
19565                 if (res) {
19566                     pkgList.add(pkgName);
19567                 } else {
19568                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
19569                     failedList.add(args);
19570                 }
19571             }
19572         }
19573
19574         // reader
19575         synchronized (mPackages) {
19576             // We didn't update the settings after removing each package;
19577             // write them now for all packages.
19578             mSettings.writeLPr();
19579         }
19580
19581         // We have to absolutely send UPDATED_MEDIA_STATUS only
19582         // after confirming that all the receivers processed the ordered
19583         // broadcast when packages get disabled, force a gc to clean things up.
19584         // and unload all the containers.
19585         if (pkgList.size() > 0) {
19586             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
19587                     new IIntentReceiver.Stub() {
19588                 public void performReceive(Intent intent, int resultCode, String data,
19589                         Bundle extras, boolean ordered, boolean sticky,
19590                         int sendingUser) throws RemoteException {
19591                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
19592                             reportStatus ? 1 : 0, 1, keys);
19593                     mHandler.sendMessage(msg);
19594                 }
19595             });
19596         } else {
19597             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
19598                     keys);
19599             mHandler.sendMessage(msg);
19600         }
19601     }
19602
19603     private void loadPrivatePackages(final VolumeInfo vol) {
19604         mHandler.post(new Runnable() {
19605             @Override
19606             public void run() {
19607                 loadPrivatePackagesInner(vol);
19608             }
19609         });
19610     }
19611
19612     private void loadPrivatePackagesInner(VolumeInfo vol) {
19613         final String volumeUuid = vol.fsUuid;
19614         if (TextUtils.isEmpty(volumeUuid)) {
19615             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
19616             return;
19617         }
19618
19619         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
19620         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
19621         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
19622
19623         final VersionInfo ver;
19624         final List<PackageSetting> packages;
19625         synchronized (mPackages) {
19626             ver = mSettings.findOrCreateVersion(volumeUuid);
19627             packages = mSettings.getVolumePackagesLPr(volumeUuid);
19628         }
19629
19630         for (PackageSetting ps : packages) {
19631             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
19632             synchronized (mInstallLock) {
19633                 final PackageParser.Package pkg;
19634                 try {
19635                     pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
19636                     loaded.add(pkg.applicationInfo);
19637
19638                 } catch (PackageManagerException e) {
19639                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
19640                 }
19641
19642                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
19643                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
19644                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
19645                                     | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19646                 }
19647             }
19648         }
19649
19650         // Reconcile app data for all started/unlocked users
19651         final StorageManager sm = mContext.getSystemService(StorageManager.class);
19652         final UserManager um = mContext.getSystemService(UserManager.class);
19653         UserManagerInternal umInternal = getUserManagerInternal();
19654         for (UserInfo user : um.getUsers()) {
19655             final int flags;
19656             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
19657                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19658             } else if (umInternal.isUserRunning(user.id)) {
19659                 flags = StorageManager.FLAG_STORAGE_DE;
19660             } else {
19661                 continue;
19662             }
19663
19664             try {
19665                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
19666                 synchronized (mInstallLock) {
19667                     reconcileAppsDataLI(volumeUuid, user.id, flags);
19668                 }
19669             } catch (IllegalStateException e) {
19670                 // Device was probably ejected, and we'll process that event momentarily
19671                 Slog.w(TAG, "Failed to prepare storage: " + e);
19672             }
19673         }
19674
19675         synchronized (mPackages) {
19676             int updateFlags = UPDATE_PERMISSIONS_ALL;
19677             if (ver.sdkVersion != mSdkVersion) {
19678                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19679                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
19680                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19681             }
19682             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19683
19684             // Yay, everything is now upgraded
19685             ver.forceCurrent();
19686
19687             mSettings.writeLPr();
19688         }
19689
19690         for (PackageFreezer freezer : freezers) {
19691             freezer.close();
19692         }
19693
19694         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
19695         sendResourcesChangedBroadcast(true, false, loaded, null);
19696     }
19697
19698     private void unloadPrivatePackages(final VolumeInfo vol) {
19699         mHandler.post(new Runnable() {
19700             @Override
19701             public void run() {
19702                 unloadPrivatePackagesInner(vol);
19703             }
19704         });
19705     }
19706
19707     private void unloadPrivatePackagesInner(VolumeInfo vol) {
19708         final String volumeUuid = vol.fsUuid;
19709         if (TextUtils.isEmpty(volumeUuid)) {
19710             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
19711             return;
19712         }
19713
19714         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
19715         synchronized (mInstallLock) {
19716         synchronized (mPackages) {
19717             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
19718             for (PackageSetting ps : packages) {
19719                 if (ps.pkg == null) continue;
19720
19721                 final ApplicationInfo info = ps.pkg.applicationInfo;
19722                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19723                 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
19724
19725                 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
19726                         "unloadPrivatePackagesInner")) {
19727                     if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
19728                             false, null)) {
19729                         unloaded.add(info);
19730                     } else {
19731                         Slog.w(TAG, "Failed to unload " + ps.codePath);
19732                     }
19733                 }
19734
19735                 // Try very hard to release any references to this package
19736                 // so we don't risk the system server being killed due to
19737                 // open FDs
19738                 AttributeCache.instance().removePackage(ps.name);
19739             }
19740
19741             mSettings.writeLPr();
19742         }
19743         }
19744
19745         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
19746         sendResourcesChangedBroadcast(false, false, unloaded, null);
19747
19748         // Try very hard to release any references to this path so we don't risk
19749         // the system server being killed due to open FDs
19750         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
19751
19752         for (int i = 0; i < 3; i++) {
19753             System.gc();
19754             System.runFinalization();
19755         }
19756     }
19757
19758     /**
19759      * Prepare storage areas for given user on all mounted devices.
19760      */
19761     void prepareUserData(int userId, int userSerial, int flags) {
19762         synchronized (mInstallLock) {
19763             final StorageManager storage = mContext.getSystemService(StorageManager.class);
19764             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19765                 final String volumeUuid = vol.getFsUuid();
19766                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
19767             }
19768         }
19769     }
19770
19771     private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags,
19772             boolean allowRecover) {
19773         // Prepare storage and verify that serial numbers are consistent; if
19774         // there's a mismatch we need to destroy to avoid leaking data
19775         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19776         try {
19777             storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
19778
19779             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
19780                 UserManagerService.enforceSerialNumber(
19781                         Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
19782                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19783                     UserManagerService.enforceSerialNumber(
19784                             Environment.getDataSystemDeDirectory(userId), userSerial);
19785                 }
19786             }
19787             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
19788                 UserManagerService.enforceSerialNumber(
19789                         Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
19790                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19791                     UserManagerService.enforceSerialNumber(
19792                             Environment.getDataSystemCeDirectory(userId), userSerial);
19793                 }
19794             }
19795
19796             synchronized (mInstallLock) {
19797                 mInstaller.createUserData(volumeUuid, userId, userSerial, flags);
19798             }
19799         } catch (Exception e) {
19800             logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid
19801                     + " because we failed to prepare: " + e);
19802             destroyUserDataLI(volumeUuid, userId,
19803                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19804
19805             if (allowRecover) {
19806                 // Try one last time; if we fail again we're really in trouble
19807                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false);
19808             }
19809         }
19810     }
19811
19812     /**
19813      * Destroy storage areas for given user on all mounted devices.
19814      */
19815     void destroyUserData(int userId, int flags) {
19816         synchronized (mInstallLock) {
19817             final StorageManager storage = mContext.getSystemService(StorageManager.class);
19818             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19819                 final String volumeUuid = vol.getFsUuid();
19820                 destroyUserDataLI(volumeUuid, userId, flags);
19821             }
19822         }
19823     }
19824
19825     private void destroyUserDataLI(String volumeUuid, int userId, int flags) {
19826         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19827         try {
19828             // Clean up app data, profile data, and media data
19829             mInstaller.destroyUserData(volumeUuid, userId, flags);
19830
19831             // Clean up system data
19832             if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19833                 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19834                     FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
19835                     FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
19836                 }
19837                 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19838                     FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
19839                 }
19840             }
19841
19842             // Data with special labels is now gone, so finish the job
19843             storage.destroyUserStorage(volumeUuid, userId, flags);
19844
19845         } catch (Exception e) {
19846             logCriticalInfo(Log.WARN,
19847                     "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e);
19848         }
19849     }
19850
19851     /**
19852      * Examine all users present on given mounted volume, and destroy data
19853      * belonging to users that are no longer valid, or whose user ID has been
19854      * recycled.
19855      */
19856     private void reconcileUsers(String volumeUuid) {
19857         final List<File> files = new ArrayList<>();
19858         Collections.addAll(files, FileUtils
19859                 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
19860         Collections.addAll(files, FileUtils
19861                 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
19862         Collections.addAll(files, FileUtils
19863                 .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
19864         Collections.addAll(files, FileUtils
19865                 .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
19866         for (File file : files) {
19867             if (!file.isDirectory()) continue;
19868
19869             final int userId;
19870             final UserInfo info;
19871             try {
19872                 userId = Integer.parseInt(file.getName());
19873                 info = sUserManager.getUserInfo(userId);
19874             } catch (NumberFormatException e) {
19875                 Slog.w(TAG, "Invalid user directory " + file);
19876                 continue;
19877             }
19878
19879             boolean destroyUser = false;
19880             if (info == null) {
19881                 logCriticalInfo(Log.WARN, "Destroying user directory " + file
19882                         + " because no matching user was found");
19883                 destroyUser = true;
19884             } else if (!mOnlyCore) {
19885                 try {
19886                     UserManagerService.enforceSerialNumber(file, info.serialNumber);
19887                 } catch (IOException e) {
19888                     logCriticalInfo(Log.WARN, "Destroying user directory " + file
19889                             + " because we failed to enforce serial number: " + e);
19890                     destroyUser = true;
19891                 }
19892             }
19893
19894             if (destroyUser) {
19895                 synchronized (mInstallLock) {
19896                     destroyUserDataLI(volumeUuid, userId,
19897                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19898                 }
19899             }
19900         }
19901     }
19902
19903     private void assertPackageKnown(String volumeUuid, String packageName)
19904             throws PackageManagerException {
19905         synchronized (mPackages) {
19906             // Normalize package name to handle renamed packages
19907             packageName = normalizePackageNameLPr(packageName);
19908
19909             final PackageSetting ps = mSettings.mPackages.get(packageName);
19910             if (ps == null) {
19911                 throw new PackageManagerException("Package " + packageName + " is unknown");
19912             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19913                 throw new PackageManagerException(
19914                         "Package " + packageName + " found on unknown volume " + volumeUuid
19915                                 + "; expected volume " + ps.volumeUuid);
19916             }
19917         }
19918     }
19919
19920     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
19921             throws PackageManagerException {
19922         synchronized (mPackages) {
19923             // Normalize package name to handle renamed packages
19924             packageName = normalizePackageNameLPr(packageName);
19925
19926             final PackageSetting ps = mSettings.mPackages.get(packageName);
19927             if (ps == null) {
19928                 throw new PackageManagerException("Package " + packageName + " is unknown");
19929             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19930                 throw new PackageManagerException(
19931                         "Package " + packageName + " found on unknown volume " + volumeUuid
19932                                 + "; expected volume " + ps.volumeUuid);
19933             } else if (!ps.getInstalled(userId)) {
19934                 throw new PackageManagerException(
19935                         "Package " + packageName + " not installed for user " + userId);
19936             }
19937         }
19938     }
19939
19940     /**
19941      * Examine all apps present on given mounted volume, and destroy apps that
19942      * aren't expected, either due to uninstallation or reinstallation on
19943      * another volume.
19944      */
19945     private void reconcileApps(String volumeUuid) {
19946         final File[] files = FileUtils
19947                 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
19948         for (File file : files) {
19949             final boolean isPackage = (isApkFile(file) || file.isDirectory())
19950                     && !PackageInstallerService.isStageName(file.getName());
19951             if (!isPackage) {
19952                 // Ignore entries which are not packages
19953                 continue;
19954             }
19955
19956             try {
19957                 final PackageLite pkg = PackageParser.parsePackageLite(file,
19958                         PackageParser.PARSE_MUST_BE_APK);
19959                 assertPackageKnown(volumeUuid, pkg.packageName);
19960
19961             } catch (PackageParserException | PackageManagerException e) {
19962                 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19963                 synchronized (mInstallLock) {
19964                     removeCodePathLI(file);
19965                 }
19966             }
19967         }
19968     }
19969
19970     /**
19971      * Reconcile all app data for the given user.
19972      * <p>
19973      * Verifies that directories exist and that ownership and labeling is
19974      * correct for all installed apps on all mounted volumes.
19975      */
19976     void reconcileAppsData(int userId, int flags) {
19977         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19978         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19979             final String volumeUuid = vol.getFsUuid();
19980             synchronized (mInstallLock) {
19981                 reconcileAppsDataLI(volumeUuid, userId, flags);
19982             }
19983         }
19984     }
19985
19986     /**
19987      * Reconcile all app data on given mounted volume.
19988      * <p>
19989      * Destroys app data that isn't expected, either due to uninstallation or
19990      * reinstallation on another volume.
19991      * <p>
19992      * Verifies that directories exist and that ownership and labeling is
19993      * correct for all installed apps.
19994      */
19995     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) {
19996         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
19997                 + Integer.toHexString(flags));
19998
19999         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
20000         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
20001
20002         // First look for stale data that doesn't belong, and check if things
20003         // have changed since we did our last restorecon
20004         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
20005             if (StorageManager.isFileEncryptedNativeOrEmulated()
20006                     && !StorageManager.isUserKeyUnlocked(userId)) {
20007                 throw new RuntimeException(
20008                         "Yikes, someone asked us to reconcile CE storage while " + userId
20009                                 + " was still locked; this would have caused massive data loss!");
20010             }
20011
20012             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
20013             for (File file : files) {
20014                 final String packageName = file.getName();
20015                 try {
20016                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
20017                 } catch (PackageManagerException e) {
20018                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
20019                     try {
20020                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
20021                                 StorageManager.FLAG_STORAGE_CE, 0);
20022                     } catch (InstallerException e2) {
20023                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
20024                     }
20025                 }
20026             }
20027         }
20028         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
20029             final File[] files = FileUtils.listFilesOrEmpty(deDir);
20030             for (File file : files) {
20031                 final String packageName = file.getName();
20032                 try {
20033                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
20034                 } catch (PackageManagerException e) {
20035                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
20036                     try {
20037                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
20038                                 StorageManager.FLAG_STORAGE_DE, 0);
20039                     } catch (InstallerException e2) {
20040                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
20041                     }
20042                 }
20043             }
20044         }
20045
20046         // Ensure that data directories are ready to roll for all packages
20047         // installed for this volume and user
20048         final List<PackageSetting> packages;
20049         synchronized (mPackages) {
20050             packages = mSettings.getVolumePackagesLPr(volumeUuid);
20051         }
20052         int preparedCount = 0;
20053         for (PackageSetting ps : packages) {
20054             final String packageName = ps.name;
20055             if (ps.pkg == null) {
20056                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
20057                 // TODO: might be due to legacy ASEC apps; we should circle back
20058                 // and reconcile again once they're scanned
20059                 continue;
20060             }
20061
20062             if (ps.getInstalled(userId)) {
20063                 prepareAppDataLIF(ps.pkg, userId, flags);
20064
20065                 if (maybeMigrateAppDataLIF(ps.pkg, userId)) {
20066                     // We may have just shuffled around app data directories, so
20067                     // prepare them one more time
20068                     prepareAppDataLIF(ps.pkg, userId, flags);
20069                 }
20070
20071                 preparedCount++;
20072             }
20073         }
20074
20075         Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
20076     }
20077
20078     /**
20079      * Prepare app data for the given app just after it was installed or
20080      * upgraded. This method carefully only touches users that it's installed
20081      * for, and it forces a restorecon to handle any seinfo changes.
20082      * <p>
20083      * Verifies that directories exist and that ownership and labeling is
20084      * correct for all installed apps. If there is an ownership mismatch, it
20085      * will try recovering system apps by wiping data; third-party app data is
20086      * left intact.
20087      * <p>
20088      * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
20089      */
20090     private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
20091         final PackageSetting ps;
20092         synchronized (mPackages) {
20093             ps = mSettings.mPackages.get(pkg.packageName);
20094             mSettings.writeKernelMappingLPr(ps);
20095         }
20096
20097         final UserManager um = mContext.getSystemService(UserManager.class);
20098         UserManagerInternal umInternal = getUserManagerInternal();
20099         for (UserInfo user : um.getUsers()) {
20100             final int flags;
20101             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
20102                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20103             } else if (umInternal.isUserRunning(user.id)) {
20104                 flags = StorageManager.FLAG_STORAGE_DE;
20105             } else {
20106                 continue;
20107             }
20108
20109             if (ps.getInstalled(user.id)) {
20110                 // TODO: when user data is locked, mark that we're still dirty
20111                 prepareAppDataLIF(pkg, user.id, flags);
20112             }
20113         }
20114     }
20115
20116     /**
20117      * Prepare app data for the given app.
20118      * <p>
20119      * Verifies that directories exist and that ownership and labeling is
20120      * correct for all installed apps. If there is an ownership mismatch, this
20121      * will try recovering system apps by wiping data; third-party app data is
20122      * left intact.
20123      */
20124     private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
20125         if (pkg == null) {
20126             Slog.wtf(TAG, "Package was null!", new Throwable());
20127             return;
20128         }
20129         prepareAppDataLeafLIF(pkg, userId, flags);
20130         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
20131         for (int i = 0; i < childCount; i++) {
20132             prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
20133         }
20134     }
20135
20136     private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
20137         if (DEBUG_APP_DATA) {
20138             Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
20139                     + Integer.toHexString(flags));
20140         }
20141
20142         final String volumeUuid = pkg.volumeUuid;
20143         final String packageName = pkg.packageName;
20144         final ApplicationInfo app = pkg.applicationInfo;
20145         final int appId = UserHandle.getAppId(app.uid);
20146
20147         Preconditions.checkNotNull(app.seinfo);
20148
20149         try {
20150             mInstaller.createAppData(volumeUuid, packageName, userId, flags,
20151                     appId, app.seinfo, app.targetSdkVersion);
20152         } catch (InstallerException e) {
20153             if (app.isSystemApp()) {
20154                 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
20155                         + ", but trying to recover: " + e);
20156                 destroyAppDataLeafLIF(pkg, userId, flags);
20157                 try {
20158                     mInstaller.createAppData(volumeUuid, packageName, userId, flags,
20159                             appId, app.seinfo, app.targetSdkVersion);
20160                     logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
20161                 } catch (InstallerException e2) {
20162                     logCriticalInfo(Log.DEBUG, "Recovery failed!");
20163                 }
20164             } else {
20165                 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
20166             }
20167         }
20168
20169         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
20170             try {
20171                 // CE storage is unlocked right now, so read out the inode and
20172                 // remember for use later when it's locked
20173                 // TODO: mark this structure as dirty so we persist it!
20174                 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId,
20175                         StorageManager.FLAG_STORAGE_CE);
20176                 synchronized (mPackages) {
20177                     final PackageSetting ps = mSettings.mPackages.get(packageName);
20178                     if (ps != null) {
20179                         ps.setCeDataInode(ceDataInode, userId);
20180                     }
20181                 }
20182             } catch (InstallerException e) {
20183                 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e);
20184             }
20185         }
20186
20187         prepareAppDataContentsLeafLIF(pkg, userId, flags);
20188     }
20189
20190     private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
20191         if (pkg == null) {
20192             Slog.wtf(TAG, "Package was null!", new Throwable());
20193             return;
20194         }
20195         prepareAppDataContentsLeafLIF(pkg, userId, flags);
20196         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
20197         for (int i = 0; i < childCount; i++) {
20198             prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
20199         }
20200     }
20201
20202     private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
20203         final String volumeUuid = pkg.volumeUuid;
20204         final String packageName = pkg.packageName;
20205         final ApplicationInfo app = pkg.applicationInfo;
20206
20207         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
20208             // Create a native library symlink only if we have native libraries
20209             // and if the native libraries are 32 bit libraries. We do not provide
20210             // this symlink for 64 bit libraries.
20211             if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
20212                 final String nativeLibPath = app.nativeLibraryDir;
20213                 try {
20214                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
20215                             nativeLibPath, userId);
20216                 } catch (InstallerException e) {
20217                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
20218                 }
20219             }
20220         }
20221     }
20222
20223     /**
20224      * For system apps on non-FBE devices, this method migrates any existing
20225      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
20226      * requested by the app.
20227      */
20228     private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
20229         if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
20230                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
20231             final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
20232                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
20233             try {
20234                 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
20235                         storageTarget);
20236             } catch (InstallerException e) {
20237                 logCriticalInfo(Log.WARN,
20238                         "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
20239             }
20240             return true;
20241         } else {
20242             return false;
20243         }
20244     }
20245
20246     public PackageFreezer freezePackage(String packageName, String killReason) {
20247         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
20248     }
20249
20250     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
20251         return new PackageFreezer(packageName, userId, killReason);
20252     }
20253
20254     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
20255             String killReason) {
20256         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
20257     }
20258
20259     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
20260             String killReason) {
20261         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
20262             return new PackageFreezer();
20263         } else {
20264             return freezePackage(packageName, userId, killReason);
20265         }
20266     }
20267
20268     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
20269             String killReason) {
20270         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
20271     }
20272
20273     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
20274             String killReason) {
20275         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
20276             return new PackageFreezer();
20277         } else {
20278             return freezePackage(packageName, userId, killReason);
20279         }
20280     }
20281
20282     /**
20283      * Class that freezes and kills the given package upon creation, and
20284      * unfreezes it upon closing. This is typically used when doing surgery on
20285      * app code/data to prevent the app from running while you're working.
20286      */
20287     private class PackageFreezer implements AutoCloseable {
20288         private final String mPackageName;
20289         private final PackageFreezer[] mChildren;
20290
20291         private final boolean mWeFroze;
20292
20293         private final AtomicBoolean mClosed = new AtomicBoolean();
20294         private final CloseGuard mCloseGuard = CloseGuard.get();
20295
20296         /**
20297          * Create and return a stub freezer that doesn't actually do anything,
20298          * typically used when someone requested
20299          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
20300          * {@link PackageManager#DELETE_DONT_KILL_APP}.
20301          */
20302         public PackageFreezer() {
20303             mPackageName = null;
20304             mChildren = null;
20305             mWeFroze = false;
20306             mCloseGuard.open("close");
20307         }
20308
20309         public PackageFreezer(String packageName, int userId, String killReason) {
20310             synchronized (mPackages) {
20311                 mPackageName = packageName;
20312                 mWeFroze = mFrozenPackages.add(mPackageName);
20313
20314                 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
20315                 if (ps != null) {
20316                     killApplication(ps.name, ps.appId, userId, killReason);
20317                 }
20318
20319                 final PackageParser.Package p = mPackages.get(packageName);
20320                 if (p != null && p.childPackages != null) {
20321                     final int N = p.childPackages.size();
20322                     mChildren = new PackageFreezer[N];
20323                     for (int i = 0; i < N; i++) {
20324                         mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
20325                                 userId, killReason);
20326                     }
20327                 } else {
20328                     mChildren = null;
20329                 }
20330             }
20331             mCloseGuard.open("close");
20332         }
20333
20334         @Override
20335         protected void finalize() throws Throwable {
20336             try {
20337                 mCloseGuard.warnIfOpen();
20338                 close();
20339             } finally {
20340                 super.finalize();
20341             }
20342         }
20343
20344         @Override
20345         public void close() {
20346             mCloseGuard.close();
20347             if (mClosed.compareAndSet(false, true)) {
20348                 synchronized (mPackages) {
20349                     if (mWeFroze) {
20350                         mFrozenPackages.remove(mPackageName);
20351                     }
20352
20353                     if (mChildren != null) {
20354                         for (PackageFreezer freezer : mChildren) {
20355                             freezer.close();
20356                         }
20357                     }
20358                 }
20359             }
20360         }
20361     }
20362
20363     /**
20364      * Verify that given package is currently frozen.
20365      */
20366     private void checkPackageFrozen(String packageName) {
20367         synchronized (mPackages) {
20368             if (!mFrozenPackages.contains(packageName)) {
20369                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
20370             }
20371         }
20372     }
20373
20374     @Override
20375     public int movePackage(final String packageName, final String volumeUuid) {
20376         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
20377
20378         final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
20379         final int moveId = mNextMoveId.getAndIncrement();
20380         mHandler.post(new Runnable() {
20381             @Override
20382             public void run() {
20383                 try {
20384                     movePackageInternal(packageName, volumeUuid, moveId, user);
20385                 } catch (PackageManagerException e) {
20386                     Slog.w(TAG, "Failed to move " + packageName, e);
20387                     mMoveCallbacks.notifyStatusChanged(moveId,
20388                             PackageManager.MOVE_FAILED_INTERNAL_ERROR);
20389                 }
20390             }
20391         });
20392         return moveId;
20393     }
20394
20395     private void movePackageInternal(final String packageName, final String volumeUuid,
20396             final int moveId, UserHandle user) throws PackageManagerException {
20397         final StorageManager storage = mContext.getSystemService(StorageManager.class);
20398         final PackageManager pm = mContext.getPackageManager();
20399
20400         final boolean currentAsec;
20401         final String currentVolumeUuid;
20402         final File codeFile;
20403         final String installerPackageName;
20404         final String packageAbiOverride;
20405         final int appId;
20406         final String seinfo;
20407         final String label;
20408         final int targetSdkVersion;
20409         final PackageFreezer freezer;
20410         final int[] installedUserIds;
20411
20412         // reader
20413         synchronized (mPackages) {
20414             final PackageParser.Package pkg = mPackages.get(packageName);
20415             final PackageSetting ps = mSettings.mPackages.get(packageName);
20416             if (pkg == null || ps == null) {
20417                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
20418             }
20419
20420             if (pkg.applicationInfo.isSystemApp()) {
20421                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
20422                         "Cannot move system application");
20423             }
20424
20425             if (pkg.applicationInfo.isExternalAsec()) {
20426                 currentAsec = true;
20427                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
20428             } else if (pkg.applicationInfo.isForwardLocked()) {
20429                 currentAsec = true;
20430                 currentVolumeUuid = "forward_locked";
20431             } else {
20432                 currentAsec = false;
20433                 currentVolumeUuid = ps.volumeUuid;
20434
20435                 final File probe = new File(pkg.codePath);
20436                 final File probeOat = new File(probe, "oat");
20437                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
20438                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20439                             "Move only supported for modern cluster style installs");
20440                 }
20441             }
20442
20443             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
20444                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20445                         "Package already moved to " + volumeUuid);
20446             }
20447             if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
20448                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
20449                         "Device admin cannot be moved");
20450             }
20451
20452             if (mFrozenPackages.contains(packageName)) {
20453                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
20454                         "Failed to move already frozen package");
20455             }
20456
20457             codeFile = new File(pkg.codePath);
20458             installerPackageName = ps.installerPackageName;
20459             packageAbiOverride = ps.cpuAbiOverrideString;
20460             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20461             seinfo = pkg.applicationInfo.seinfo;
20462             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
20463             targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
20464             freezer = freezePackage(packageName, "movePackageInternal");
20465             installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
20466         }
20467
20468         final Bundle extras = new Bundle();
20469         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
20470         extras.putString(Intent.EXTRA_TITLE, label);
20471         mMoveCallbacks.notifyCreated(moveId, extras);
20472
20473         int installFlags;
20474         final boolean moveCompleteApp;
20475         final File measurePath;
20476
20477         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
20478             installFlags = INSTALL_INTERNAL;
20479             moveCompleteApp = !currentAsec;
20480             measurePath = Environment.getDataAppDirectory(volumeUuid);
20481         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
20482             installFlags = INSTALL_EXTERNAL;
20483             moveCompleteApp = false;
20484             measurePath = storage.getPrimaryPhysicalVolume().getPath();
20485         } else {
20486             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
20487             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
20488                     || !volume.isMountedWritable()) {
20489                 freezer.close();
20490                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20491                         "Move location not mounted private volume");
20492             }
20493
20494             Preconditions.checkState(!currentAsec);
20495
20496             installFlags = INSTALL_INTERNAL;
20497             moveCompleteApp = true;
20498             measurePath = Environment.getDataAppDirectory(volumeUuid);
20499         }
20500
20501         final PackageStats stats = new PackageStats(null, -1);
20502         synchronized (mInstaller) {
20503             for (int userId : installedUserIds) {
20504                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
20505                     freezer.close();
20506                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20507                             "Failed to measure package size");
20508                 }
20509             }
20510         }
20511
20512         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
20513                 + stats.dataSize);
20514
20515         final long startFreeBytes = measurePath.getFreeSpace();
20516         final long sizeBytes;
20517         if (moveCompleteApp) {
20518             sizeBytes = stats.codeSize + stats.dataSize;
20519         } else {
20520             sizeBytes = stats.codeSize;
20521         }
20522
20523         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
20524             freezer.close();
20525             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20526                     "Not enough free space to move");
20527         }
20528
20529         mMoveCallbacks.notifyStatusChanged(moveId, 10);
20530
20531         final CountDownLatch installedLatch = new CountDownLatch(1);
20532         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
20533             @Override
20534             public void onUserActionRequired(Intent intent) throws RemoteException {
20535                 throw new IllegalStateException();
20536             }
20537
20538             @Override
20539             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
20540                     Bundle extras) throws RemoteException {
20541                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
20542                         + PackageManager.installStatusToString(returnCode, msg));
20543
20544                 installedLatch.countDown();
20545                 freezer.close();
20546
20547                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
20548                 switch (status) {
20549                     case PackageInstaller.STATUS_SUCCESS:
20550                         mMoveCallbacks.notifyStatusChanged(moveId,
20551                                 PackageManager.MOVE_SUCCEEDED);
20552                         break;
20553                     case PackageInstaller.STATUS_FAILURE_STORAGE:
20554                         mMoveCallbacks.notifyStatusChanged(moveId,
20555                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
20556                         break;
20557                     default:
20558                         mMoveCallbacks.notifyStatusChanged(moveId,
20559                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
20560                         break;
20561                 }
20562             }
20563         };
20564
20565         final MoveInfo move;
20566         if (moveCompleteApp) {
20567             // Kick off a thread to report progress estimates
20568             new Thread() {
20569                 @Override
20570                 public void run() {
20571                     while (true) {
20572                         try {
20573                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
20574                                 break;
20575                             }
20576                         } catch (InterruptedException ignored) {
20577                         }
20578
20579                         final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
20580                         final int progress = 10 + (int) MathUtils.constrain(
20581                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
20582                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
20583                     }
20584                 }
20585             }.start();
20586
20587             final String dataAppName = codeFile.getName();
20588             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
20589                     dataAppName, appId, seinfo, targetSdkVersion);
20590         } else {
20591             move = null;
20592         }
20593
20594         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
20595
20596         final Message msg = mHandler.obtainMessage(INIT_COPY);
20597         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
20598         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
20599                 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
20600                 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/);
20601         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
20602         msg.obj = params;
20603
20604         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
20605                 System.identityHashCode(msg.obj));
20606         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
20607                 System.identityHashCode(msg.obj));
20608
20609         mHandler.sendMessage(msg);
20610     }
20611
20612     @Override
20613     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
20614         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
20615
20616         final int realMoveId = mNextMoveId.getAndIncrement();
20617         final Bundle extras = new Bundle();
20618         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
20619         mMoveCallbacks.notifyCreated(realMoveId, extras);
20620
20621         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
20622             @Override
20623             public void onCreated(int moveId, Bundle extras) {
20624                 // Ignored
20625             }
20626
20627             @Override
20628             public void onStatusChanged(int moveId, int status, long estMillis) {
20629                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
20630             }
20631         };
20632
20633         final StorageManager storage = mContext.getSystemService(StorageManager.class);
20634         storage.setPrimaryStorageUuid(volumeUuid, callback);
20635         return realMoveId;
20636     }
20637
20638     @Override
20639     public int getMoveStatus(int moveId) {
20640         mContext.enforceCallingOrSelfPermission(
20641                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20642         return mMoveCallbacks.mLastStatus.get(moveId);
20643     }
20644
20645     @Override
20646     public void registerMoveCallback(IPackageMoveObserver callback) {
20647         mContext.enforceCallingOrSelfPermission(
20648                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20649         mMoveCallbacks.register(callback);
20650     }
20651
20652     @Override
20653     public void unregisterMoveCallback(IPackageMoveObserver callback) {
20654         mContext.enforceCallingOrSelfPermission(
20655                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20656         mMoveCallbacks.unregister(callback);
20657     }
20658
20659     @Override
20660     public boolean setInstallLocation(int loc) {
20661         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
20662                 null);
20663         if (getInstallLocation() == loc) {
20664             return true;
20665         }
20666         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
20667                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
20668             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
20669                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
20670             return true;
20671         }
20672         return false;
20673    }
20674
20675     @Override
20676     public int getInstallLocation() {
20677         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
20678                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
20679                 PackageHelper.APP_INSTALL_AUTO);
20680     }
20681
20682     /** Called by UserManagerService */
20683     void cleanUpUser(UserManagerService userManager, int userHandle) {
20684         synchronized (mPackages) {
20685             mDirtyUsers.remove(userHandle);
20686             mUserNeedsBadging.delete(userHandle);
20687             mSettings.removeUserLPw(userHandle);
20688             mPendingBroadcasts.remove(userHandle);
20689             mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
20690             removeUnusedPackagesLPw(userManager, userHandle);
20691         }
20692     }
20693
20694     /**
20695      * We're removing userHandle and would like to remove any downloaded packages
20696      * that are no longer in use by any other user.
20697      * @param userHandle the user being removed
20698      */
20699     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
20700         final boolean DEBUG_CLEAN_APKS = false;
20701         int [] users = userManager.getUserIds();
20702         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
20703         while (psit.hasNext()) {
20704             PackageSetting ps = psit.next();
20705             if (ps.pkg == null) {
20706                 continue;
20707             }
20708             final String packageName = ps.pkg.packageName;
20709             // Skip over if system app
20710             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
20711                 continue;
20712             }
20713             if (DEBUG_CLEAN_APKS) {
20714                 Slog.i(TAG, "Checking package " + packageName);
20715             }
20716             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
20717             if (keep) {
20718                 if (DEBUG_CLEAN_APKS) {
20719                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
20720                 }
20721             } else {
20722                 for (int i = 0; i < users.length; i++) {
20723                     if (users[i] != userHandle && ps.getInstalled(users[i])) {
20724                         keep = true;
20725                         if (DEBUG_CLEAN_APKS) {
20726                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
20727                                     + users[i]);
20728                         }
20729                         break;
20730                     }
20731                 }
20732             }
20733             if (!keep) {
20734                 if (DEBUG_CLEAN_APKS) {
20735                     Slog.i(TAG, "  Removing package " + packageName);
20736                 }
20737                 mHandler.post(new Runnable() {
20738                     public void run() {
20739                         deletePackageX(packageName, userHandle, 0);
20740                     } //end run
20741                 });
20742             }
20743         }
20744     }
20745
20746     /** Called by UserManagerService */
20747     void createNewUser(int userId) {
20748         synchronized (mInstallLock) {
20749             mSettings.createNewUserLI(this, mInstaller, userId);
20750         }
20751         synchronized (mPackages) {
20752             scheduleWritePackageRestrictionsLocked(userId);
20753             scheduleWritePackageListLocked(userId);
20754             applyFactoryDefaultBrowserLPw(userId);
20755             primeDomainVerificationsLPw(userId);
20756         }
20757     }
20758
20759     void onNewUserCreated(final int userId) {
20760         mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20761         // If permission review for legacy apps is required, we represent
20762         // dagerous permissions for such apps as always granted runtime
20763         // permissions to keep per user flag state whether review is needed.
20764         // Hence, if a new user is added we have to propagate dangerous
20765         // permission grants for these legacy apps.
20766         if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
20767             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
20768                     | UPDATE_PERMISSIONS_REPLACE_ALL);
20769         }
20770     }
20771
20772     @Override
20773     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
20774         mContext.enforceCallingOrSelfPermission(
20775                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
20776                 "Only package verification agents can read the verifier device identity");
20777
20778         synchronized (mPackages) {
20779             return mSettings.getVerifierDeviceIdentityLPw();
20780         }
20781     }
20782
20783     @Override
20784     public void setPermissionEnforced(String permission, boolean enforced) {
20785         // TODO: Now that we no longer change GID for storage, this should to away.
20786         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
20787                 "setPermissionEnforced");
20788         if (READ_EXTERNAL_STORAGE.equals(permission)) {
20789             synchronized (mPackages) {
20790                 if (mSettings.mReadExternalStorageEnforced == null
20791                         || mSettings.mReadExternalStorageEnforced != enforced) {
20792                     mSettings.mReadExternalStorageEnforced = enforced;
20793                     mSettings.writeLPr();
20794                 }
20795             }
20796             // kill any non-foreground processes so we restart them and
20797             // grant/revoke the GID.
20798             final IActivityManager am = ActivityManagerNative.getDefault();
20799             if (am != null) {
20800                 final long token = Binder.clearCallingIdentity();
20801                 try {
20802                     am.killProcessesBelowForeground("setPermissionEnforcement");
20803                 } catch (RemoteException e) {
20804                 } finally {
20805                     Binder.restoreCallingIdentity(token);
20806                 }
20807             }
20808         } else {
20809             throw new IllegalArgumentException("No selective enforcement for " + permission);
20810         }
20811     }
20812
20813     @Override
20814     @Deprecated
20815     public boolean isPermissionEnforced(String permission) {
20816         return true;
20817     }
20818
20819     @Override
20820     public boolean isStorageLow() {
20821         final long token = Binder.clearCallingIdentity();
20822         try {
20823             final DeviceStorageMonitorInternal
20824                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
20825             if (dsm != null) {
20826                 return dsm.isMemoryLow();
20827             } else {
20828                 return false;
20829             }
20830         } finally {
20831             Binder.restoreCallingIdentity(token);
20832         }
20833     }
20834
20835     @Override
20836     public IPackageInstaller getPackageInstaller() {
20837         return mInstallerService;
20838     }
20839
20840     private boolean userNeedsBadging(int userId) {
20841         int index = mUserNeedsBadging.indexOfKey(userId);
20842         if (index < 0) {
20843             final UserInfo userInfo;
20844             final long token = Binder.clearCallingIdentity();
20845             try {
20846                 userInfo = sUserManager.getUserInfo(userId);
20847             } finally {
20848                 Binder.restoreCallingIdentity(token);
20849             }
20850             final boolean b;
20851             if (userInfo != null && userInfo.isManagedProfile()) {
20852                 b = true;
20853             } else {
20854                 b = false;
20855             }
20856             mUserNeedsBadging.put(userId, b);
20857             return b;
20858         }
20859         return mUserNeedsBadging.valueAt(index);
20860     }
20861
20862     @Override
20863     public KeySet getKeySetByAlias(String packageName, String alias) {
20864         if (packageName == null || alias == null) {
20865             return null;
20866         }
20867         synchronized(mPackages) {
20868             final PackageParser.Package pkg = mPackages.get(packageName);
20869             if (pkg == null) {
20870                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20871                 throw new IllegalArgumentException("Unknown package: " + packageName);
20872             }
20873             KeySetManagerService ksms = mSettings.mKeySetManagerService;
20874             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
20875         }
20876     }
20877
20878     @Override
20879     public KeySet getSigningKeySet(String packageName) {
20880         if (packageName == null) {
20881             return null;
20882         }
20883         synchronized(mPackages) {
20884             final PackageParser.Package pkg = mPackages.get(packageName);
20885             if (pkg == null) {
20886                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20887                 throw new IllegalArgumentException("Unknown package: " + packageName);
20888             }
20889             if (pkg.applicationInfo.uid != Binder.getCallingUid()
20890                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
20891                 throw new SecurityException("May not access signing KeySet of other apps.");
20892             }
20893             KeySetManagerService ksms = mSettings.mKeySetManagerService;
20894             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
20895         }
20896     }
20897
20898     @Override
20899     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
20900         if (packageName == null || ks == null) {
20901             return false;
20902         }
20903         synchronized(mPackages) {
20904             final PackageParser.Package pkg = mPackages.get(packageName);
20905             if (pkg == null) {
20906                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20907                 throw new IllegalArgumentException("Unknown package: " + packageName);
20908             }
20909             IBinder ksh = ks.getToken();
20910             if (ksh instanceof KeySetHandle) {
20911                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
20912                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
20913             }
20914             return false;
20915         }
20916     }
20917
20918     @Override
20919     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
20920         if (packageName == null || ks == null) {
20921             return false;
20922         }
20923         synchronized(mPackages) {
20924             final PackageParser.Package pkg = mPackages.get(packageName);
20925             if (pkg == null) {
20926                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20927                 throw new IllegalArgumentException("Unknown package: " + packageName);
20928             }
20929             IBinder ksh = ks.getToken();
20930             if (ksh instanceof KeySetHandle) {
20931                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
20932                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
20933             }
20934             return false;
20935         }
20936     }
20937
20938     private void deletePackageIfUnusedLPr(final String packageName) {
20939         PackageSetting ps = mSettings.mPackages.get(packageName);
20940         if (ps == null) {
20941             return;
20942         }
20943         if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
20944             // TODO Implement atomic delete if package is unused
20945             // It is currently possible that the package will be deleted even if it is installed
20946             // after this method returns.
20947             mHandler.post(new Runnable() {
20948                 public void run() {
20949                     deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
20950                 }
20951             });
20952         }
20953     }
20954
20955     /**
20956      * Check and throw if the given before/after packages would be considered a
20957      * downgrade.
20958      */
20959     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
20960             throws PackageManagerException {
20961         if (after.versionCode < before.mVersionCode) {
20962             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20963                     "Update version code " + after.versionCode + " is older than current "
20964                     + before.mVersionCode);
20965         } else if (after.versionCode == before.mVersionCode) {
20966             if (after.baseRevisionCode < before.baseRevisionCode) {
20967                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20968                         "Update base revision code " + after.baseRevisionCode
20969                         + " is older than current " + before.baseRevisionCode);
20970             }
20971
20972             if (!ArrayUtils.isEmpty(after.splitNames)) {
20973                 for (int i = 0; i < after.splitNames.length; i++) {
20974                     final String splitName = after.splitNames[i];
20975                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
20976                     if (j != -1) {
20977                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
20978                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20979                                     "Update split " + splitName + " revision code "
20980                                     + after.splitRevisionCodes[i] + " is older than current "
20981                                     + before.splitRevisionCodes[j]);
20982                         }
20983                     }
20984                 }
20985             }
20986         }
20987     }
20988
20989     private static class MoveCallbacks extends Handler {
20990         private static final int MSG_CREATED = 1;
20991         private static final int MSG_STATUS_CHANGED = 2;
20992
20993         private final RemoteCallbackList<IPackageMoveObserver>
20994                 mCallbacks = new RemoteCallbackList<>();
20995
20996         private final SparseIntArray mLastStatus = new SparseIntArray();
20997
20998         public MoveCallbacks(Looper looper) {
20999             super(looper);
21000         }
21001
21002         public void register(IPackageMoveObserver callback) {
21003             mCallbacks.register(callback);
21004         }
21005
21006         public void unregister(IPackageMoveObserver callback) {
21007             mCallbacks.unregister(callback);
21008         }
21009
21010         @Override
21011         public void handleMessage(Message msg) {
21012             final SomeArgs args = (SomeArgs) msg.obj;
21013             final int n = mCallbacks.beginBroadcast();
21014             for (int i = 0; i < n; i++) {
21015                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
21016                 try {
21017                     invokeCallback(callback, msg.what, args);
21018                 } catch (RemoteException ignored) {
21019                 }
21020             }
21021             mCallbacks.finishBroadcast();
21022             args.recycle();
21023         }
21024
21025         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
21026                 throws RemoteException {
21027             switch (what) {
21028                 case MSG_CREATED: {
21029                     callback.onCreated(args.argi1, (Bundle) args.arg2);
21030                     break;
21031                 }
21032                 case MSG_STATUS_CHANGED: {
21033                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
21034                     break;
21035                 }
21036             }
21037         }
21038
21039         private void notifyCreated(int moveId, Bundle extras) {
21040             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
21041
21042             final SomeArgs args = SomeArgs.obtain();
21043             args.argi1 = moveId;
21044             args.arg2 = extras;
21045             obtainMessage(MSG_CREATED, args).sendToTarget();
21046         }
21047
21048         private void notifyStatusChanged(int moveId, int status) {
21049             notifyStatusChanged(moveId, status, -1);
21050         }
21051
21052         private void notifyStatusChanged(int moveId, int status, long estMillis) {
21053             Slog.v(TAG, "Move " + moveId + " status " + status);
21054
21055             final SomeArgs args = SomeArgs.obtain();
21056             args.argi1 = moveId;
21057             args.argi2 = status;
21058             args.arg3 = estMillis;
21059             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
21060
21061             synchronized (mLastStatus) {
21062                 mLastStatus.put(moveId, status);
21063             }
21064         }
21065     }
21066
21067     private final static class OnPermissionChangeListeners extends Handler {
21068         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
21069
21070         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
21071                 new RemoteCallbackList<>();
21072
21073         public OnPermissionChangeListeners(Looper looper) {
21074             super(looper);
21075         }
21076
21077         @Override
21078         public void handleMessage(Message msg) {
21079             switch (msg.what) {
21080                 case MSG_ON_PERMISSIONS_CHANGED: {
21081                     final int uid = msg.arg1;
21082                     handleOnPermissionsChanged(uid);
21083                 } break;
21084             }
21085         }
21086
21087         public void addListenerLocked(IOnPermissionsChangeListener listener) {
21088             mPermissionListeners.register(listener);
21089
21090         }
21091
21092         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
21093             mPermissionListeners.unregister(listener);
21094         }
21095
21096         public void onPermissionsChanged(int uid) {
21097             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
21098                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
21099             }
21100         }
21101
21102         private void handleOnPermissionsChanged(int uid) {
21103             final int count = mPermissionListeners.beginBroadcast();
21104             try {
21105                 for (int i = 0; i < count; i++) {
21106                     IOnPermissionsChangeListener callback = mPermissionListeners
21107                             .getBroadcastItem(i);
21108                     try {
21109                         callback.onPermissionsChanged(uid);
21110                     } catch (RemoteException e) {
21111                         Log.e(TAG, "Permission listener is dead", e);
21112                     }
21113                 }
21114             } finally {
21115                 mPermissionListeners.finishBroadcast();
21116             }
21117         }
21118     }
21119
21120     private class PackageManagerInternalImpl extends PackageManagerInternal {
21121         @Override
21122         public void setLocationPackagesProvider(PackagesProvider provider) {
21123             synchronized (mPackages) {
21124                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
21125             }
21126         }
21127
21128         @Override
21129         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
21130             synchronized (mPackages) {
21131                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
21132             }
21133         }
21134
21135         @Override
21136         public void setSmsAppPackagesProvider(PackagesProvider provider) {
21137             synchronized (mPackages) {
21138                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
21139             }
21140         }
21141
21142         @Override
21143         public void setDialerAppPackagesProvider(PackagesProvider provider) {
21144             synchronized (mPackages) {
21145                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
21146             }
21147         }
21148
21149         @Override
21150         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
21151             synchronized (mPackages) {
21152                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
21153             }
21154         }
21155
21156         @Override
21157         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
21158             synchronized (mPackages) {
21159                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
21160             }
21161         }
21162
21163         @Override
21164         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
21165             synchronized (mPackages) {
21166                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
21167                         packageName, userId);
21168             }
21169         }
21170
21171         @Override
21172         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
21173             synchronized (mPackages) {
21174                 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
21175                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
21176                         packageName, userId);
21177             }
21178         }
21179
21180         @Override
21181         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
21182             synchronized (mPackages) {
21183                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
21184                         packageName, userId);
21185             }
21186         }
21187
21188         @Override
21189         public void setKeepUninstalledPackages(final List<String> packageList) {
21190             Preconditions.checkNotNull(packageList);
21191             List<String> removedFromList = null;
21192             synchronized (mPackages) {
21193                 if (mKeepUninstalledPackages != null) {
21194                     final int packagesCount = mKeepUninstalledPackages.size();
21195                     for (int i = 0; i < packagesCount; i++) {
21196                         String oldPackage = mKeepUninstalledPackages.get(i);
21197                         if (packageList != null && packageList.contains(oldPackage)) {
21198                             continue;
21199                         }
21200                         if (removedFromList == null) {
21201                             removedFromList = new ArrayList<>();
21202                         }
21203                         removedFromList.add(oldPackage);
21204                     }
21205                 }
21206                 mKeepUninstalledPackages = new ArrayList<>(packageList);
21207                 if (removedFromList != null) {
21208                     final int removedCount = removedFromList.size();
21209                     for (int i = 0; i < removedCount; i++) {
21210                         deletePackageIfUnusedLPr(removedFromList.get(i));
21211                     }
21212                 }
21213             }
21214         }
21215
21216         @Override
21217         public boolean isPermissionsReviewRequired(String packageName, int userId) {
21218             synchronized (mPackages) {
21219                 // If we do not support permission review, done.
21220                 if (!mPermissionReviewRequired && !Build.PERMISSIONS_REVIEW_REQUIRED) {
21221                     return false;
21222                 }
21223
21224                 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
21225                 if (packageSetting == null) {
21226                     return false;
21227                 }
21228
21229                 // Permission review applies only to apps not supporting the new permission model.
21230                 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
21231                     return false;
21232                 }
21233
21234                 // Legacy apps have the permission and get user consent on launch.
21235                 PermissionsState permissionsState = packageSetting.getPermissionsState();
21236                 return permissionsState.isPermissionReviewRequired(userId);
21237             }
21238         }
21239
21240         @Override
21241         public ApplicationInfo getApplicationInfo(String packageName, int userId) {
21242             return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
21243         }
21244
21245         @Override
21246         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21247                 int userId) {
21248             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
21249         }
21250
21251         @Override
21252         public void setDeviceAndProfileOwnerPackages(
21253                 int deviceOwnerUserId, String deviceOwnerPackage,
21254                 SparseArray<String> profileOwnerPackages) {
21255             mProtectedPackages.setDeviceAndProfileOwnerPackages(
21256                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
21257         }
21258
21259         @Override
21260         public boolean isPackageDataProtected(int userId, String packageName) {
21261             return mProtectedPackages.isPackageDataProtected(userId, packageName);
21262         }
21263
21264         @Override
21265         public boolean wasPackageEverLaunched(String packageName, int userId) {
21266             synchronized (mPackages) {
21267                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
21268             }
21269         }
21270     }
21271
21272     @Override
21273     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
21274         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
21275         synchronized (mPackages) {
21276             final long identity = Binder.clearCallingIdentity();
21277             try {
21278                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
21279                         packageNames, userId);
21280             } finally {
21281                 Binder.restoreCallingIdentity(identity);
21282             }
21283         }
21284     }
21285
21286     private static void enforceSystemOrPhoneCaller(String tag) {
21287         int callingUid = Binder.getCallingUid();
21288         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
21289             throw new SecurityException(
21290                     "Cannot call " + tag + " from UID " + callingUid);
21291         }
21292     }
21293
21294     boolean isHistoricalPackageUsageAvailable() {
21295         return mPackageUsage.isHistoricalPackageUsageAvailable();
21296     }
21297
21298     /**
21299      * Return a <b>copy</b> of the collection of packages known to the package manager.
21300      * @return A copy of the values of mPackages.
21301      */
21302     Collection<PackageParser.Package> getPackages() {
21303         synchronized (mPackages) {
21304             return new ArrayList<>(mPackages.values());
21305         }
21306     }
21307
21308     /**
21309      * Logs process start information (including base APK hash) to the security log.
21310      * @hide
21311      */
21312     public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
21313             String apkFile, int pid) {
21314         if (!SecurityLog.isLoggingEnabled()) {
21315             return;
21316         }
21317         Bundle data = new Bundle();
21318         data.putLong("startTimestamp", System.currentTimeMillis());
21319         data.putString("processName", processName);
21320         data.putInt("uid", uid);
21321         data.putString("seinfo", seinfo);
21322         data.putString("apkFile", apkFile);
21323         data.putInt("pid", pid);
21324         Message msg = mProcessLoggingHandler.obtainMessage(
21325                 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
21326         msg.setData(data);
21327         mProcessLoggingHandler.sendMessage(msg);
21328     }
21329
21330     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
21331         return mCompilerStats.getPackageStats(pkgName);
21332     }
21333
21334     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
21335         return getOrCreateCompilerPackageStats(pkg.packageName);
21336     }
21337
21338     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
21339         return mCompilerStats.getOrCreatePackageStats(pkgName);
21340     }
21341
21342     public void deleteCompilerPackageStats(String pkgName) {
21343         mCompilerStats.deletePackageStats(pkgName);
21344     }
21345 }