• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Context;
113 import android.content.IIntentReceiver;
114 import android.content.Intent;
115 import android.content.IntentFilter;
116 import android.content.IntentSender;
117 import android.content.IntentSender.SendIntentException;
118 import android.content.ServiceConnection;
119 import android.content.pm.ActivityInfo;
120 import android.content.pm.ApplicationInfo;
121 import android.content.pm.AppsQueryHelper;
122 import android.content.pm.ComponentInfo;
123 import android.content.pm.EphemeralApplicationInfo;
124 import android.content.pm.EphemeralResolveInfo;
125 import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
126 import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
127 import android.content.pm.FeatureInfo;
128 import android.content.pm.IOnPermissionsChangeListener;
129 import android.content.pm.IPackageDataObserver;
130 import android.content.pm.IPackageDeleteObserver;
131 import android.content.pm.IPackageDeleteObserver2;
132 import android.content.pm.IPackageInstallObserver2;
133 import android.content.pm.IPackageInstaller;
134 import android.content.pm.IPackageManager;
135 import android.content.pm.IPackageMoveObserver;
136 import android.content.pm.IPackageStatsObserver;
137 import android.content.pm.InstrumentationInfo;
138 import android.content.pm.IntentFilterVerificationInfo;
139 import android.content.pm.KeySet;
140 import android.content.pm.PackageCleanItem;
141 import android.content.pm.PackageInfo;
142 import android.content.pm.PackageInfoLite;
143 import android.content.pm.PackageInstaller;
144 import android.content.pm.PackageManager;
145 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
146 import android.content.pm.PackageManagerInternal;
147 import android.content.pm.PackageParser;
148 import android.content.pm.PackageParser.ActivityIntentInfo;
149 import android.content.pm.PackageParser.PackageLite;
150 import android.content.pm.PackageParser.PackageParserException;
151 import android.content.pm.PackageStats;
152 import android.content.pm.PackageUserState;
153 import android.content.pm.ParceledListSlice;
154 import android.content.pm.PermissionGroupInfo;
155 import android.content.pm.PermissionInfo;
156 import android.content.pm.ProviderInfo;
157 import android.content.pm.ResolveInfo;
158 import android.content.pm.ServiceInfo;
159 import android.content.pm.Signature;
160 import android.content.pm.UserInfo;
161 import android.content.pm.VerifierDeviceIdentity;
162 import android.content.pm.VerifierInfo;
163 import android.content.res.Resources;
164 import android.graphics.Bitmap;
165 import android.hardware.display.DisplayManager;
166 import android.net.Uri;
167 import android.os.Binder;
168 import android.os.Build;
169 import android.os.Bundle;
170 import android.os.Debug;
171 import android.os.Environment;
172 import android.os.Environment.UserEnvironment;
173 import android.os.FileUtils;
174 import android.os.Handler;
175 import android.os.IBinder;
176 import android.os.Looper;
177 import android.os.Message;
178 import android.os.Parcel;
179 import android.os.ParcelFileDescriptor;
180 import android.os.Process;
181 import android.os.RemoteCallbackList;
182 import android.os.RemoteException;
183 import android.os.ResultReceiver;
184 import android.os.SELinux;
185 import android.os.ServiceManager;
186 import android.os.SystemClock;
187 import android.os.SystemProperties;
188 import android.os.Trace;
189 import android.os.UserHandle;
190 import android.os.UserManager;
191 import android.os.UserManagerInternal;
192 import android.os.storage.IMountService;
193 import android.os.storage.MountServiceInternal;
194 import android.os.storage.StorageEventListener;
195 import android.os.storage.StorageManager;
196 import android.os.storage.VolumeInfo;
197 import android.os.storage.VolumeRecord;
198 import android.provider.Settings.Global;
199 import android.security.KeyStore;
200 import android.security.SystemKeyStore;
201 import android.system.ErrnoException;
202 import android.system.Os;
203 import android.text.TextUtils;
204 import android.text.format.DateUtils;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.DisplayMetrics;
208 import android.util.EventLog;
209 import android.util.ExceptionUtils;
210 import android.util.Log;
211 import android.util.LogPrinter;
212 import android.util.MathUtils;
213 import android.util.PrintStreamPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.SparseBooleanArray;
217 import android.util.SparseIntArray;
218 import android.util.Xml;
219 import android.util.jar.StrictJarFile;
220 import android.view.Display;
221 
222 import com.android.internal.R;
223 import com.android.internal.annotations.GuardedBy;
224 import com.android.internal.app.IMediaContainerService;
225 import com.android.internal.app.ResolverActivity;
226 import com.android.internal.content.NativeLibraryHelper;
227 import com.android.internal.content.PackageHelper;
228 import com.android.internal.logging.MetricsLogger;
229 import com.android.internal.os.IParcelFileDescriptorFactory;
230 import com.android.internal.os.InstallerConnection.InstallerException;
231 import com.android.internal.os.SomeArgs;
232 import com.android.internal.os.Zygote;
233 import com.android.internal.telephony.CarrierAppUtils;
234 import com.android.internal.util.ArrayUtils;
235 import com.android.internal.util.FastPrintWriter;
236 import com.android.internal.util.FastXmlSerializer;
237 import com.android.internal.util.IndentingPrintWriter;
238 import com.android.internal.util.Preconditions;
239 import com.android.internal.util.XmlUtils;
240 import com.android.server.AttributeCache;
241 import com.android.server.EventLogTags;
242 import com.android.server.FgThread;
243 import com.android.server.IntentResolver;
244 import com.android.server.LocalServices;
245 import com.android.server.ServiceThread;
246 import com.android.server.SystemConfig;
247 import com.android.server.Watchdog;
248 import com.android.server.net.NetworkPolicyManagerInternal;
249 import com.android.server.pm.PermissionsState.PermissionState;
250 import com.android.server.pm.Settings.DatabaseVersion;
251 import com.android.server.pm.Settings.VersionInfo;
252 import com.android.server.storage.DeviceStorageMonitorInternal;
253 
254 import dalvik.system.CloseGuard;
255 import dalvik.system.DexFile;
256 import dalvik.system.VMRuntime;
257 
258 import libcore.io.IoUtils;
259 import libcore.util.EmptyArray;
260 
261 import org.xmlpull.v1.XmlPullParser;
262 import org.xmlpull.v1.XmlPullParserException;
263 import org.xmlpull.v1.XmlSerializer;
264 
265 import java.io.BufferedOutputStream;
266 import java.io.BufferedReader;
267 import java.io.ByteArrayInputStream;
268 import java.io.ByteArrayOutputStream;
269 import java.io.File;
270 import java.io.FileDescriptor;
271 import java.io.FileInputStream;
272 import java.io.FileNotFoundException;
273 import java.io.FileOutputStream;
274 import java.io.FileReader;
275 import java.io.FilenameFilter;
276 import java.io.IOException;
277 import java.io.PrintWriter;
278 import java.nio.charset.StandardCharsets;
279 import java.security.DigestInputStream;
280 import java.security.MessageDigest;
281 import java.security.NoSuchAlgorithmException;
282 import java.security.PublicKey;
283 import java.security.cert.Certificate;
284 import java.security.cert.CertificateEncodingException;
285 import java.security.cert.CertificateException;
286 import java.text.SimpleDateFormat;
287 import java.util.ArrayList;
288 import java.util.Arrays;
289 import java.util.Collection;
290 import java.util.Collections;
291 import java.util.Comparator;
292 import java.util.Date;
293 import java.util.HashSet;
294 import java.util.Iterator;
295 import java.util.List;
296 import java.util.Map;
297 import java.util.Objects;
298 import java.util.Set;
299 import java.util.concurrent.CountDownLatch;
300 import java.util.concurrent.TimeUnit;
301 import java.util.concurrent.atomic.AtomicBoolean;
302 import java.util.concurrent.atomic.AtomicInteger;
303 
304 /**
305  * Keep track of all those APKs everywhere.
306  * <p>
307  * Internally there are two important locks:
308  * <ul>
309  * <li>{@link #mPackages} is used to guard all in-memory parsed package details
310  * and other related state. It is a fine-grained lock that should only be held
311  * momentarily, as it's one of the most contended locks in the system.
312  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
313  * operations typically involve heavy lifting of application data on disk. Since
314  * {@code installd} is single-threaded, and it's operations can often be slow,
315  * this lock should never be acquired while already holding {@link #mPackages}.
316  * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
317  * holding {@link #mInstallLock}.
318  * </ul>
319  * Many internal methods rely on the caller to hold the appropriate locks, and
320  * this contract is expressed through method name suffixes:
321  * <ul>
322  * <li>fooLI(): the caller must hold {@link #mInstallLock}
323  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
324  * being modified must be frozen
325  * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
326  * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
327  * </ul>
328  * <p>
329  * Because this class is very central to the platform's security; please run all
330  * CTS and unit tests whenever making modifications:
331  *
332  * <pre>
333  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
334  * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
335  * </pre>
336  */
337 public class PackageManagerService extends IPackageManager.Stub {
338     static final String TAG = "PackageManager";
339     static final boolean DEBUG_SETTINGS = false;
340     static final boolean DEBUG_PREFERRED = false;
341     static final boolean DEBUG_UPGRADE = false;
342     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
343     private static final boolean DEBUG_BACKUP = false;
344     private static final boolean DEBUG_INSTALL = false;
345     private static final boolean DEBUG_REMOVE = false;
346     private static final boolean DEBUG_BROADCASTS = false;
347     private static final boolean DEBUG_SHOW_INFO = false;
348     private static final boolean DEBUG_PACKAGE_INFO = false;
349     private static final boolean DEBUG_INTENT_MATCHING = false;
350     private static final boolean DEBUG_PACKAGE_SCANNING = false;
351     private static final boolean DEBUG_VERIFY = false;
352     private static final boolean DEBUG_FILTERS = false;
353 
354     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
355     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
356     // user, but by default initialize to this.
357     static final boolean DEBUG_DEXOPT = false;
358 
359     private static final boolean DEBUG_ABI_SELECTION = false;
360     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
361     private static final boolean DEBUG_TRIAGED_MISSING = false;
362     private static final boolean DEBUG_APP_DATA = false;
363 
364     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
365 
366     private static final boolean DISABLE_EPHEMERAL_APPS = !Build.IS_DEBUGGABLE;
367 
368     private static final int RADIO_UID = Process.PHONE_UID;
369     private static final int LOG_UID = Process.LOG_UID;
370     private static final int NFC_UID = Process.NFC_UID;
371     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
372     private static final int SHELL_UID = Process.SHELL_UID;
373 
374     // Cap the size of permission trees that 3rd party apps can define
375     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
376 
377     // Suffix used during package installation when copying/moving
378     // package apks to install directory.
379     private static final String INSTALL_PACKAGE_SUFFIX = "-";
380 
381     static final int SCAN_NO_DEX = 1<<1;
382     static final int SCAN_FORCE_DEX = 1<<2;
383     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
384     static final int SCAN_NEW_INSTALL = 1<<4;
385     static final int SCAN_NO_PATHS = 1<<5;
386     static final int SCAN_UPDATE_TIME = 1<<6;
387     static final int SCAN_DEFER_DEX = 1<<7;
388     static final int SCAN_BOOTING = 1<<8;
389     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
390     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
391     static final int SCAN_REPLACING = 1<<11;
392     static final int SCAN_REQUIRE_KNOWN = 1<<12;
393     static final int SCAN_MOVE = 1<<13;
394     static final int SCAN_INITIAL = 1<<14;
395     static final int SCAN_CHECK_ONLY = 1<<15;
396     static final int SCAN_DONT_KILL_APP = 1<<17;
397     static final int SCAN_IGNORE_FROZEN = 1<<18;
398 
399     static final int REMOVE_CHATTY = 1<<16;
400 
401     private static final int[] EMPTY_INT_ARRAY = new int[0];
402 
403     /**
404      * Timeout (in milliseconds) after which the watchdog should declare that
405      * our handler thread is wedged.  The usual default for such things is one
406      * minute but we sometimes do very lengthy I/O operations on this thread,
407      * such as installing multi-gigabyte applications, so ours needs to be longer.
408      */
409     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
410 
411     /**
412      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
413      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
414      * settings entry if available, otherwise we use the hardcoded default.  If it's been
415      * more than this long since the last fstrim, we force one during the boot sequence.
416      *
417      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
418      * one gets run at the next available charging+idle time.  This final mandatory
419      * no-fstrim check kicks in only of the other scheduling criteria is never met.
420      */
421     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
422 
423     /**
424      * Whether verification is enabled by default.
425      */
426     private static final boolean DEFAULT_VERIFY_ENABLE = true;
427 
428     /**
429      * The default maximum time to wait for the verification agent to return in
430      * milliseconds.
431      */
432     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
433 
434     /**
435      * The default response for package verification timeout.
436      *
437      * This can be either PackageManager.VERIFICATION_ALLOW or
438      * PackageManager.VERIFICATION_REJECT.
439      */
440     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
441 
442     static final String PLATFORM_PACKAGE_NAME = "android";
443 
444     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
445 
446     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
447             DEFAULT_CONTAINER_PACKAGE,
448             "com.android.defcontainer.DefaultContainerService");
449 
450     private static final String KILL_APP_REASON_GIDS_CHANGED =
451             "permission grant or revoke changed gids";
452 
453     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
454             "permissions revoked";
455 
456     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
457 
458     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
459 
460     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000;
461     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5;
462 
463     /** Permission grant: not grant the permission. */
464     private static final int GRANT_DENIED = 1;
465 
466     /** Permission grant: grant the permission as an install permission. */
467     private static final int GRANT_INSTALL = 2;
468 
469     /** Permission grant: grant the permission as a runtime one. */
470     private static final int GRANT_RUNTIME = 3;
471 
472     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
473     private static final int GRANT_UPGRADE = 4;
474 
475     /** Canonical intent used to identify what counts as a "web browser" app */
476     private static final Intent sBrowserIntent;
477     static {
478         sBrowserIntent = new Intent();
479         sBrowserIntent.setAction(Intent.ACTION_VIEW);
480         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
481         sBrowserIntent.setData(Uri.parse("http:"));
482     }
483 
484     /**
485      * The set of all protected actions [i.e. those actions for which a high priority
486      * intent filter is disallowed].
487      */
488     private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
489     static {
490         PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
491         PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
492         PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
493         PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
494     }
495 
496     // Compilation reasons.
497     public static final int REASON_FIRST_BOOT = 0;
498     public static final int REASON_BOOT = 1;
499     public static final int REASON_INSTALL = 2;
500     public static final int REASON_BACKGROUND_DEXOPT = 3;
501     public static final int REASON_AB_OTA = 4;
502     public static final int REASON_NON_SYSTEM_LIBRARY = 5;
503     public static final int REASON_SHARED_APK = 6;
504     public static final int REASON_FORCED_DEXOPT = 7;
505     public static final int REASON_CORE_APP = 8;
506 
507     public static final int REASON_LAST = REASON_CORE_APP;
508 
509     /** Special library name that skips shared libraries check during compilation. */
510     private static final String SKIP_SHARED_LIBRARY_CHECK = "&";
511 
512     final ServiceThread mHandlerThread;
513 
514     final PackageHandler mHandler;
515 
516     private final ProcessLoggingHandler mProcessLoggingHandler;
517 
518     /**
519      * Messages for {@link #mHandler} that need to wait for system ready before
520      * being dispatched.
521      */
522     private ArrayList<Message> mPostSystemReadyMessages;
523 
524     final int mSdkVersion = Build.VERSION.SDK_INT;
525 
526     final Context mContext;
527     final boolean mFactoryTest;
528     final boolean mOnlyCore;
529     final DisplayMetrics mMetrics;
530     final int mDefParseFlags;
531     final String[] mSeparateProcesses;
532     final boolean mIsUpgrade;
533     final boolean mIsPreNUpgrade;
534 
535     /** The location for ASEC container files on internal storage. */
536     final String mAsecInternalPath;
537 
538     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
539     // LOCK HELD.  Can be called with mInstallLock held.
540     @GuardedBy("mInstallLock")
541     final Installer mInstaller;
542 
543     /** Directory where installed third-party apps stored */
544     final File mAppInstallDir;
545     final File mEphemeralInstallDir;
546 
547     /**
548      * Directory to which applications installed internally have their
549      * 32 bit native libraries copied.
550      */
551     private File mAppLib32InstallDir;
552 
553     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
554     // apps.
555     final File mDrmAppPrivateInstallDir;
556 
557     // ----------------------------------------------------------------
558 
559     // Lock for state used when installing and doing other long running
560     // operations.  Methods that must be called with this lock held have
561     // the suffix "LI".
562     final Object mInstallLock = new Object();
563 
564     // ----------------------------------------------------------------
565 
566     // Keys are String (package name), values are Package.  This also serves
567     // as the lock for the global state.  Methods that must be called with
568     // this lock held have the prefix "LP".
569     @GuardedBy("mPackages")
570     final ArrayMap<String, PackageParser.Package> mPackages =
571             new ArrayMap<String, PackageParser.Package>();
572 
573     final ArrayMap<String, Set<String>> mKnownCodebase =
574             new ArrayMap<String, Set<String>>();
575 
576     // Tracks available target package names -> overlay package paths.
577     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
578         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
579 
580     /**
581      * Tracks new system packages [received in an OTA] that we expect to
582      * find updated user-installed versions. Keys are package name, values
583      * are package location.
584      */
585     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
586     /**
587      * Tracks high priority intent filters for protected actions. During boot, certain
588      * filter actions are protected and should never be allowed to have a high priority
589      * intent filter for them. However, there is one, and only one exception -- the
590      * setup wizard. It must be able to define a high priority intent filter for these
591      * actions to ensure there are no escapes from the wizard. We need to delay processing
592      * of these during boot as we need to look at all of the system packages in order
593      * to know which component is the setup wizard.
594      */
595     private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
596     /**
597      * Whether or not processing protected filters should be deferred.
598      */
599     private boolean mDeferProtectedFilters = true;
600 
601     /**
602      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
603      */
604     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
605     /**
606      * Whether or not system app permissions should be promoted from install to runtime.
607      */
608     boolean mPromoteSystemApps;
609 
610     @GuardedBy("mPackages")
611     final Settings mSettings;
612 
613     /**
614      * Set of package names that are currently "frozen", which means active
615      * surgery is being done on the code/data for that package. The platform
616      * will refuse to launch frozen packages to avoid race conditions.
617      *
618      * @see PackageFreezer
619      */
620     @GuardedBy("mPackages")
621     final ArraySet<String> mFrozenPackages = new ArraySet<>();
622 
623     final ProtectedPackages mProtectedPackages;
624 
625     boolean mFirstBoot;
626 
627     // System configuration read by SystemConfig.
628     final int[] mGlobalGids;
629     final SparseArray<ArraySet<String>> mSystemPermissions;
630     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
631 
632     // If mac_permissions.xml was found for seinfo labeling.
633     boolean mFoundPolicyFile;
634 
635     private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
636 
637     public static final class SharedLibraryEntry {
638         public final String path;
639         public final String apk;
640 
SharedLibraryEntry(String _path, String _apk)641         SharedLibraryEntry(String _path, String _apk) {
642             path = _path;
643             apk = _apk;
644         }
645     }
646 
647     // Currently known shared libraries.
648     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
649             new ArrayMap<String, SharedLibraryEntry>();
650 
651     // All available activities, for your resolving pleasure.
652     final ActivityIntentResolver mActivities =
653             new ActivityIntentResolver();
654 
655     // All available receivers, for your resolving pleasure.
656     final ActivityIntentResolver mReceivers =
657             new ActivityIntentResolver();
658 
659     // All available services, for your resolving pleasure.
660     final ServiceIntentResolver mServices = new ServiceIntentResolver();
661 
662     // All available providers, for your resolving pleasure.
663     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
664 
665     // Mapping from provider base names (first directory in content URI codePath)
666     // to the provider information.
667     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
668             new ArrayMap<String, PackageParser.Provider>();
669 
670     // Mapping from instrumentation class names to info about them.
671     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
672             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
673 
674     // Mapping from permission names to info about them.
675     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
676             new ArrayMap<String, PackageParser.PermissionGroup>();
677 
678     // Packages whose data we have transfered into another package, thus
679     // should no longer exist.
680     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
681 
682     // Broadcast actions that are only available to the system.
683     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
684 
685     /** List of packages waiting for verification. */
686     final SparseArray<PackageVerificationState> mPendingVerification
687             = new SparseArray<PackageVerificationState>();
688 
689     /** Set of packages associated with each app op permission. */
690     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
691 
692     final PackageInstallerService mInstallerService;
693 
694     private final PackageDexOptimizer mPackageDexOptimizer;
695 
696     private AtomicInteger mNextMoveId = new AtomicInteger();
697     private final MoveCallbacks mMoveCallbacks;
698 
699     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
700 
701     // Cache of users who need badging.
702     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
703 
704     /** Token for keys in mPendingVerification. */
705     private int mPendingVerificationToken = 0;
706 
707     volatile boolean mSystemReady;
708     volatile boolean mSafeMode;
709     volatile boolean mHasSystemUidErrors;
710 
711     ApplicationInfo mAndroidApplication;
712     final ActivityInfo mResolveActivity = new ActivityInfo();
713     final ResolveInfo mResolveInfo = new ResolveInfo();
714     ComponentName mResolveComponentName;
715     PackageParser.Package mPlatformPackage;
716     ComponentName mCustomResolverComponentName;
717 
718     boolean mResolverReplaced = false;
719 
720     private final @Nullable ComponentName mIntentFilterVerifierComponent;
721     private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
722 
723     private int mIntentFilterVerificationToken = 0;
724 
725     /** Component that knows whether or not an ephemeral application exists */
726     final ComponentName mEphemeralResolverComponent;
727     /** The service connection to the ephemeral resolver */
728     final EphemeralResolverConnection mEphemeralResolverConnection;
729 
730     /** Component used to install ephemeral applications */
731     final ComponentName mEphemeralInstallerComponent;
732     final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
733     final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
734 
735     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
736             = new SparseArray<IntentFilterVerificationState>();
737 
738     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
739 
740     // List of packages names to keep cached, even if they are uninstalled for all users
741     private List<String> mKeepUninstalledPackages;
742 
743     private UserManagerInternal mUserManagerInternal;
744 
745     private static class IFVerificationParams {
746         PackageParser.Package pkg;
747         boolean replacing;
748         int userId;
749         int verifierUid;
750 
IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, int _userId, int _verifierUid)751         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
752                 int _userId, int _verifierUid) {
753             pkg = _pkg;
754             replacing = _replacing;
755             userId = _userId;
756             replacing = _replacing;
757             verifierUid = _verifierUid;
758         }
759     }
760 
761     private interface IntentFilterVerifier<T extends IntentFilter> {
addOneIntentFilterVerification(int verifierId, int userId, int verificationId, T filter, String packageName)762         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
763                                                T filter, String packageName);
startVerifications(int userId)764         void startVerifications(int userId);
receiveVerificationResponse(int verificationId)765         void receiveVerificationResponse(int verificationId);
766     }
767 
768     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
769         private Context mContext;
770         private ComponentName mIntentFilterVerifierComponent;
771         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
772 
IntentVerifierProxy(Context context, ComponentName verifierComponent)773         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
774             mContext = context;
775             mIntentFilterVerifierComponent = verifierComponent;
776         }
777 
getDefaultScheme()778         private String getDefaultScheme() {
779             return IntentFilter.SCHEME_HTTPS;
780         }
781 
782         @Override
startVerifications(int userId)783         public void startVerifications(int userId) {
784             // Launch verifications requests
785             int count = mCurrentIntentFilterVerifications.size();
786             for (int n=0; n<count; n++) {
787                 int verificationId = mCurrentIntentFilterVerifications.get(n);
788                 final IntentFilterVerificationState ivs =
789                         mIntentFilterVerificationStates.get(verificationId);
790 
791                 String packageName = ivs.getPackageName();
792 
793                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
794                 final int filterCount = filters.size();
795                 ArraySet<String> domainsSet = new ArraySet<>();
796                 for (int m=0; m<filterCount; m++) {
797                     PackageParser.ActivityIntentInfo filter = filters.get(m);
798                     domainsSet.addAll(filter.getHostsList());
799                 }
800                 ArrayList<String> domainsList = new ArrayList<>(domainsSet);
801                 synchronized (mPackages) {
802                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
803                             packageName, domainsList) != null) {
804                         scheduleWriteSettingsLocked();
805                     }
806                 }
807                 sendVerificationRequest(userId, verificationId, ivs);
808             }
809             mCurrentIntentFilterVerifications.clear();
810         }
811 
sendVerificationRequest(int userId, int verificationId, IntentFilterVerificationState ivs)812         private void sendVerificationRequest(int userId, int verificationId,
813                 IntentFilterVerificationState ivs) {
814 
815             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
816             verificationIntent.putExtra(
817                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
818                     verificationId);
819             verificationIntent.putExtra(
820                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
821                     getDefaultScheme());
822             verificationIntent.putExtra(
823                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
824                     ivs.getHostsString());
825             verificationIntent.putExtra(
826                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
827                     ivs.getPackageName());
828             verificationIntent.setComponent(mIntentFilterVerifierComponent);
829             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
830 
831             UserHandle user = new UserHandle(userId);
832             mContext.sendBroadcastAsUser(verificationIntent, user);
833             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
834                     "Sending IntentFilter verification broadcast");
835         }
836 
receiveVerificationResponse(int verificationId)837         public void receiveVerificationResponse(int verificationId) {
838             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
839 
840             final boolean verified = ivs.isVerified();
841 
842             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
843             final int count = filters.size();
844             if (DEBUG_DOMAIN_VERIFICATION) {
845                 Slog.i(TAG, "Received verification response " + verificationId
846                         + " for " + count + " filters, verified=" + verified);
847             }
848             for (int n=0; n<count; n++) {
849                 PackageParser.ActivityIntentInfo filter = filters.get(n);
850                 filter.setVerified(verified);
851 
852                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
853                         + " verified with result:" + verified + " and hosts:"
854                         + ivs.getHostsString());
855             }
856 
857             mIntentFilterVerificationStates.remove(verificationId);
858 
859             final String packageName = ivs.getPackageName();
860             IntentFilterVerificationInfo ivi = null;
861 
862             synchronized (mPackages) {
863                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
864             }
865             if (ivi == null) {
866                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
867                         + verificationId + " packageName:" + packageName);
868                 return;
869             }
870             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
871                     "Updating IntentFilterVerificationInfo for package " + packageName
872                             +" verificationId:" + verificationId);
873 
874             synchronized (mPackages) {
875                 if (verified) {
876                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
877                 } else {
878                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
879                 }
880                 scheduleWriteSettingsLocked();
881 
882                 final int userId = ivs.getUserId();
883                 if (userId != UserHandle.USER_ALL) {
884                     final int userStatus =
885                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
886 
887                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
888                     boolean needUpdate = false;
889 
890                     // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
891                     // already been set by the User thru the Disambiguation dialog
892                     switch (userStatus) {
893                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
894                             if (verified) {
895                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
896                             } else {
897                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
898                             }
899                             needUpdate = true;
900                             break;
901 
902                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
903                             if (verified) {
904                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
905                                 needUpdate = true;
906                             }
907                             break;
908 
909                         default:
910                             // Nothing to do
911                     }
912 
913                     if (needUpdate) {
914                         mSettings.updateIntentFilterVerificationStatusLPw(
915                                 packageName, updatedStatus, userId);
916                         scheduleWritePackageRestrictionsLocked(userId);
917                     }
918                 }
919             }
920         }
921 
922         @Override
addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, ActivityIntentInfo filter, String packageName)923         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
924                     ActivityIntentInfo filter, String packageName) {
925             if (!hasValidDomains(filter)) {
926                 return false;
927             }
928             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
929             if (ivs == null) {
930                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
931                         packageName);
932             }
933             if (DEBUG_DOMAIN_VERIFICATION) {
934                 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
935             }
936             ivs.addFilter(filter);
937             return true;
938         }
939 
createDomainVerificationState(int verifierUid, int userId, int verificationId, String packageName)940         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
941                 int userId, int verificationId, String packageName) {
942             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
943                     verifierUid, userId, packageName);
944             ivs.setPendingState();
945             synchronized (mPackages) {
946                 mIntentFilterVerificationStates.append(verificationId, ivs);
947                 mCurrentIntentFilterVerifications.add(verificationId);
948             }
949             return ivs;
950         }
951     }
952 
hasValidDomains(ActivityIntentInfo filter)953     private static boolean hasValidDomains(ActivityIntentInfo filter) {
954         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
955                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
956                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
957     }
958 
959     // Set of pending broadcasts for aggregating enable/disable of components.
960     static class PendingPackageBroadcasts {
961         // for each user id, a map of <package name -> components within that package>
962         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
963 
PendingPackageBroadcasts()964         public PendingPackageBroadcasts() {
965             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
966         }
967 
get(int userId, String packageName)968         public ArrayList<String> get(int userId, String packageName) {
969             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
970             return packages.get(packageName);
971         }
972 
put(int userId, String packageName, ArrayList<String> components)973         public void put(int userId, String packageName, ArrayList<String> components) {
974             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
975             packages.put(packageName, components);
976         }
977 
remove(int userId, String packageName)978         public void remove(int userId, String packageName) {
979             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
980             if (packages != null) {
981                 packages.remove(packageName);
982             }
983         }
984 
remove(int userId)985         public void remove(int userId) {
986             mUidMap.remove(userId);
987         }
988 
userIdCount()989         public int userIdCount() {
990             return mUidMap.size();
991         }
992 
userIdAt(int n)993         public int userIdAt(int n) {
994             return mUidMap.keyAt(n);
995         }
996 
packagesForUserId(int userId)997         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
998             return mUidMap.get(userId);
999         }
1000 
size()1001         public int size() {
1002             // total number of pending broadcast entries across all userIds
1003             int num = 0;
1004             for (int i = 0; i< mUidMap.size(); i++) {
1005                 num += mUidMap.valueAt(i).size();
1006             }
1007             return num;
1008         }
1009 
clear()1010         public void clear() {
1011             mUidMap.clear();
1012         }
1013 
getOrAllocate(int userId)1014         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1015             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1016             if (map == null) {
1017                 map = new ArrayMap<String, ArrayList<String>>();
1018                 mUidMap.put(userId, map);
1019             }
1020             return map;
1021         }
1022     }
1023     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1024 
1025     // Service Connection to remote media container service to copy
1026     // package uri's from external media onto secure containers
1027     // or internal storage.
1028     private IMediaContainerService mContainerService = null;
1029 
1030     static final int SEND_PENDING_BROADCAST = 1;
1031     static final int MCS_BOUND = 3;
1032     static final int END_COPY = 4;
1033     static final int INIT_COPY = 5;
1034     static final int MCS_UNBIND = 6;
1035     static final int START_CLEANING_PACKAGE = 7;
1036     static final int FIND_INSTALL_LOC = 8;
1037     static final int POST_INSTALL = 9;
1038     static final int MCS_RECONNECT = 10;
1039     static final int MCS_GIVE_UP = 11;
1040     static final int UPDATED_MEDIA_STATUS = 12;
1041     static final int WRITE_SETTINGS = 13;
1042     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1043     static final int PACKAGE_VERIFIED = 15;
1044     static final int CHECK_PENDING_VERIFICATION = 16;
1045     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1046     static final int INTENT_FILTER_VERIFIED = 18;
1047     static final int WRITE_PACKAGE_LIST = 19;
1048 
1049     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1050 
1051     // Delay time in millisecs
1052     static final int BROADCAST_DELAY = 10 * 1000;
1053 
1054     static UserManagerService sUserManager;
1055 
1056     // Stores a list of users whose package restrictions file needs to be updated
1057     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1058 
1059     final private DefaultContainerConnection mDefContainerConn =
1060             new DefaultContainerConnection();
1061     class DefaultContainerConnection implements ServiceConnection {
onServiceConnected(ComponentName name, IBinder service)1062         public void onServiceConnected(ComponentName name, IBinder service) {
1063             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1064             IMediaContainerService imcs =
1065                 IMediaContainerService.Stub.asInterface(service);
1066             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1067         }
1068 
onServiceDisconnected(ComponentName name)1069         public void onServiceDisconnected(ComponentName name) {
1070             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1071         }
1072     }
1073 
1074     // Recordkeeping of restore-after-install operations that are currently in flight
1075     // between the Package Manager and the Backup Manager
1076     static class PostInstallData {
1077         public InstallArgs args;
1078         public PackageInstalledInfo res;
1079 
PostInstallData(InstallArgs _a, PackageInstalledInfo _r)1080         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1081             args = _a;
1082             res = _r;
1083         }
1084     }
1085 
1086     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1087     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1088 
1089     // XML tags for backup/restore of various bits of state
1090     private static final String TAG_PREFERRED_BACKUP = "pa";
1091     private static final String TAG_DEFAULT_APPS = "da";
1092     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1093 
1094     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1095     private static final String TAG_ALL_GRANTS = "rt-grants";
1096     private static final String TAG_GRANT = "grant";
1097     private static final String ATTR_PACKAGE_NAME = "pkg";
1098 
1099     private static final String TAG_PERMISSION = "perm";
1100     private static final String ATTR_PERMISSION_NAME = "name";
1101     private static final String ATTR_IS_GRANTED = "g";
1102     private static final String ATTR_USER_SET = "set";
1103     private static final String ATTR_USER_FIXED = "fixed";
1104     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1105 
1106     // System/policy permission grants are not backed up
1107     private static final int SYSTEM_RUNTIME_GRANT_MASK =
1108             FLAG_PERMISSION_POLICY_FIXED
1109             | FLAG_PERMISSION_SYSTEM_FIXED
1110             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1111 
1112     // And we back up these user-adjusted states
1113     private static final int USER_RUNTIME_GRANT_MASK =
1114             FLAG_PERMISSION_USER_SET
1115             | FLAG_PERMISSION_USER_FIXED
1116             | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1117 
1118     final @Nullable String mRequiredVerifierPackage;
1119     final @NonNull String mRequiredInstallerPackage;
1120     final @Nullable String mSetupWizardPackage;
1121     final @NonNull String mServicesSystemSharedLibraryPackageName;
1122     final @NonNull String mSharedSystemSharedLibraryPackageName;
1123 
1124     private final PackageUsage mPackageUsage = new PackageUsage();
1125     private final CompilerStats mCompilerStats = new CompilerStats();
1126 
1127     class PackageHandler extends Handler {
1128         private boolean mBound = false;
1129         final ArrayList<HandlerParams> mPendingInstalls =
1130             new ArrayList<HandlerParams>();
1131 
connectToService()1132         private boolean connectToService() {
1133             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1134                     " DefaultContainerService");
1135             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1136             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1137             if (mContext.bindServiceAsUser(service, mDefContainerConn,
1138                     Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1139                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1140                 mBound = true;
1141                 return true;
1142             }
1143             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1144             return false;
1145         }
1146 
disconnectService()1147         private void disconnectService() {
1148             mContainerService = null;
1149             mBound = false;
1150             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1151             mContext.unbindService(mDefContainerConn);
1152             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1153         }
1154 
PackageHandler(Looper looper)1155         PackageHandler(Looper looper) {
1156             super(looper);
1157         }
1158 
handleMessage(Message msg)1159         public void handleMessage(Message msg) {
1160             try {
1161                 doHandleMessage(msg);
1162             } finally {
1163                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1164             }
1165         }
1166 
doHandleMessage(Message msg)1167         void doHandleMessage(Message msg) {
1168             switch (msg.what) {
1169                 case INIT_COPY: {
1170                     HandlerParams params = (HandlerParams) msg.obj;
1171                     int idx = mPendingInstalls.size();
1172                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1173                     // If a bind was already initiated we dont really
1174                     // need to do anything. The pending install
1175                     // will be processed later on.
1176                     if (!mBound) {
1177                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1178                                 System.identityHashCode(mHandler));
1179                         // If this is the only one pending we might
1180                         // have to bind to the service again.
1181                         if (!connectToService()) {
1182                             Slog.e(TAG, "Failed to bind to media container service");
1183                             params.serviceError();
1184                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1185                                     System.identityHashCode(mHandler));
1186                             if (params.traceMethod != null) {
1187                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1188                                         params.traceCookie);
1189                             }
1190                             return;
1191                         } else {
1192                             // Once we bind to the service, the first
1193                             // pending request will be processed.
1194                             mPendingInstalls.add(idx, params);
1195                         }
1196                     } else {
1197                         mPendingInstalls.add(idx, params);
1198                         // Already bound to the service. Just make
1199                         // sure we trigger off processing the first request.
1200                         if (idx == 0) {
1201                             mHandler.sendEmptyMessage(MCS_BOUND);
1202                         }
1203                     }
1204                     break;
1205                 }
1206                 case MCS_BOUND: {
1207                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1208                     if (msg.obj != null) {
1209                         mContainerService = (IMediaContainerService) msg.obj;
1210                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1211                                 System.identityHashCode(mHandler));
1212                     }
1213                     if (mContainerService == null) {
1214                         if (!mBound) {
1215                             // Something seriously wrong since we are not bound and we are not
1216                             // waiting for connection. Bail out.
1217                             Slog.e(TAG, "Cannot bind to media container service");
1218                             for (HandlerParams params : mPendingInstalls) {
1219                                 // Indicate service bind error
1220                                 params.serviceError();
1221                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1222                                         System.identityHashCode(params));
1223                                 if (params.traceMethod != null) {
1224                                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1225                                             params.traceMethod, params.traceCookie);
1226                                 }
1227                                 return;
1228                             }
1229                             mPendingInstalls.clear();
1230                         } else {
1231                             Slog.w(TAG, "Waiting to connect to media container service");
1232                         }
1233                     } else if (mPendingInstalls.size() > 0) {
1234                         HandlerParams params = mPendingInstalls.get(0);
1235                         if (params != null) {
1236                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1237                                     System.identityHashCode(params));
1238                             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1239                             if (params.startCopy()) {
1240                                 // We are done...  look for more work or to
1241                                 // go idle.
1242                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
1243                                         "Checking for more work or unbind...");
1244                                 // Delete pending install
1245                                 if (mPendingInstalls.size() > 0) {
1246                                     mPendingInstalls.remove(0);
1247                                 }
1248                                 if (mPendingInstalls.size() == 0) {
1249                                     if (mBound) {
1250                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
1251                                                 "Posting delayed MCS_UNBIND");
1252                                         removeMessages(MCS_UNBIND);
1253                                         Message ubmsg = obtainMessage(MCS_UNBIND);
1254                                         // Unbind after a little delay, to avoid
1255                                         // continual thrashing.
1256                                         sendMessageDelayed(ubmsg, 10000);
1257                                     }
1258                                 } else {
1259                                     // There are more pending requests in queue.
1260                                     // Just post MCS_BOUND message to trigger processing
1261                                     // of next pending install.
1262                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
1263                                             "Posting MCS_BOUND for next work");
1264                                     mHandler.sendEmptyMessage(MCS_BOUND);
1265                                 }
1266                             }
1267                             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1268                         }
1269                     } else {
1270                         // Should never happen ideally.
1271                         Slog.w(TAG, "Empty queue");
1272                     }
1273                     break;
1274                 }
1275                 case MCS_RECONNECT: {
1276                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1277                     if (mPendingInstalls.size() > 0) {
1278                         if (mBound) {
1279                             disconnectService();
1280                         }
1281                         if (!connectToService()) {
1282                             Slog.e(TAG, "Failed to bind to media container service");
1283                             for (HandlerParams params : mPendingInstalls) {
1284                                 // Indicate service bind error
1285                                 params.serviceError();
1286                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1287                                         System.identityHashCode(params));
1288                             }
1289                             mPendingInstalls.clear();
1290                         }
1291                     }
1292                     break;
1293                 }
1294                 case MCS_UNBIND: {
1295                     // If there is no actual work left, then time to unbind.
1296                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1297 
1298                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1299                         if (mBound) {
1300                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1301 
1302                             disconnectService();
1303                         }
1304                     } else if (mPendingInstalls.size() > 0) {
1305                         // There are more pending requests in queue.
1306                         // Just post MCS_BOUND message to trigger processing
1307                         // of next pending install.
1308                         mHandler.sendEmptyMessage(MCS_BOUND);
1309                     }
1310 
1311                     break;
1312                 }
1313                 case MCS_GIVE_UP: {
1314                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1315                     HandlerParams params = mPendingInstalls.remove(0);
1316                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1317                             System.identityHashCode(params));
1318                     break;
1319                 }
1320                 case SEND_PENDING_BROADCAST: {
1321                     String packages[];
1322                     ArrayList<String> components[];
1323                     int size = 0;
1324                     int uids[];
1325                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1326                     synchronized (mPackages) {
1327                         if (mPendingBroadcasts == null) {
1328                             return;
1329                         }
1330                         size = mPendingBroadcasts.size();
1331                         if (size <= 0) {
1332                             // Nothing to be done. Just return
1333                             return;
1334                         }
1335                         packages = new String[size];
1336                         components = new ArrayList[size];
1337                         uids = new int[size];
1338                         int i = 0;  // filling out the above arrays
1339 
1340                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1341                             int packageUserId = mPendingBroadcasts.userIdAt(n);
1342                             Iterator<Map.Entry<String, ArrayList<String>>> it
1343                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
1344                                             .entrySet().iterator();
1345                             while (it.hasNext() && i < size) {
1346                                 Map.Entry<String, ArrayList<String>> ent = it.next();
1347                                 packages[i] = ent.getKey();
1348                                 components[i] = ent.getValue();
1349                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1350                                 uids[i] = (ps != null)
1351                                         ? UserHandle.getUid(packageUserId, ps.appId)
1352                                         : -1;
1353                                 i++;
1354                             }
1355                         }
1356                         size = i;
1357                         mPendingBroadcasts.clear();
1358                     }
1359                     // Send broadcasts
1360                     for (int i = 0; i < size; i++) {
1361                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1362                     }
1363                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1364                     break;
1365                 }
1366                 case START_CLEANING_PACKAGE: {
1367                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1368                     final String packageName = (String)msg.obj;
1369                     final int userId = msg.arg1;
1370                     final boolean andCode = msg.arg2 != 0;
1371                     synchronized (mPackages) {
1372                         if (userId == UserHandle.USER_ALL) {
1373                             int[] users = sUserManager.getUserIds();
1374                             for (int user : users) {
1375                                 mSettings.addPackageToCleanLPw(
1376                                         new PackageCleanItem(user, packageName, andCode));
1377                             }
1378                         } else {
1379                             mSettings.addPackageToCleanLPw(
1380                                     new PackageCleanItem(userId, packageName, andCode));
1381                         }
1382                     }
1383                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1384                     startCleaningPackages();
1385                 } break;
1386                 case POST_INSTALL: {
1387                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1388 
1389                     PostInstallData data = mRunningInstalls.get(msg.arg1);
1390                     final boolean didRestore = (msg.arg2 != 0);
1391                     mRunningInstalls.delete(msg.arg1);
1392 
1393                     if (data != null) {
1394                         InstallArgs args = data.args;
1395                         PackageInstalledInfo parentRes = data.res;
1396 
1397                         final boolean grantPermissions = (args.installFlags
1398                                 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1399                         final boolean killApp = (args.installFlags
1400                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1401                         final String[] grantedPermissions = args.installGrantPermissions;
1402 
1403                         // Handle the parent package
1404                         handlePackagePostInstall(parentRes, grantPermissions, killApp,
1405                                 grantedPermissions, didRestore, args.installerPackageName,
1406                                 args.observer);
1407 
1408                         // Handle the child packages
1409                         final int childCount = (parentRes.addedChildPackages != null)
1410                                 ? parentRes.addedChildPackages.size() : 0;
1411                         for (int i = 0; i < childCount; i++) {
1412                             PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1413                             handlePackagePostInstall(childRes, grantPermissions, killApp,
1414                                     grantedPermissions, false, args.installerPackageName,
1415                                     args.observer);
1416                         }
1417 
1418                         // Log tracing if needed
1419                         if (args.traceMethod != null) {
1420                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1421                                     args.traceCookie);
1422                         }
1423                     } else {
1424                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1425                     }
1426 
1427                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1428                 } break;
1429                 case UPDATED_MEDIA_STATUS: {
1430                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1431                     boolean reportStatus = msg.arg1 == 1;
1432                     boolean doGc = msg.arg2 == 1;
1433                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1434                     if (doGc) {
1435                         // Force a gc to clear up stale containers.
1436                         Runtime.getRuntime().gc();
1437                     }
1438                     if (msg.obj != null) {
1439                         @SuppressWarnings("unchecked")
1440                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1441                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1442                         // Unload containers
1443                         unloadAllContainers(args);
1444                     }
1445                     if (reportStatus) {
1446                         try {
1447                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1448                             PackageHelper.getMountService().finishMediaUpdate();
1449                         } catch (RemoteException e) {
1450                             Log.e(TAG, "MountService not running?");
1451                         }
1452                     }
1453                 } break;
1454                 case WRITE_SETTINGS: {
1455                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1456                     synchronized (mPackages) {
1457                         removeMessages(WRITE_SETTINGS);
1458                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1459                         mSettings.writeLPr();
1460                         mDirtyUsers.clear();
1461                     }
1462                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1463                 } break;
1464                 case WRITE_PACKAGE_RESTRICTIONS: {
1465                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1466                     synchronized (mPackages) {
1467                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1468                         for (int userId : mDirtyUsers) {
1469                             mSettings.writePackageRestrictionsLPr(userId);
1470                         }
1471                         mDirtyUsers.clear();
1472                     }
1473                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1474                 } break;
1475                 case WRITE_PACKAGE_LIST: {
1476                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1477                     synchronized (mPackages) {
1478                         removeMessages(WRITE_PACKAGE_LIST);
1479                         mSettings.writePackageListLPr(msg.arg1);
1480                     }
1481                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1482                 } break;
1483                 case CHECK_PENDING_VERIFICATION: {
1484                     final int verificationId = msg.arg1;
1485                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1486 
1487                     if ((state != null) && !state.timeoutExtended()) {
1488                         final InstallArgs args = state.getInstallArgs();
1489                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1490 
1491                         Slog.i(TAG, "Verification timed out for " + originUri);
1492                         mPendingVerification.remove(verificationId);
1493 
1494                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1495 
1496                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1497                             Slog.i(TAG, "Continuing with installation of " + originUri);
1498                             state.setVerifierResponse(Binder.getCallingUid(),
1499                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1500                             broadcastPackageVerified(verificationId, originUri,
1501                                     PackageManager.VERIFICATION_ALLOW,
1502                                     state.getInstallArgs().getUser());
1503                             try {
1504                                 ret = args.copyApk(mContainerService, true);
1505                             } catch (RemoteException e) {
1506                                 Slog.e(TAG, "Could not contact the ContainerService");
1507                             }
1508                         } else {
1509                             broadcastPackageVerified(verificationId, originUri,
1510                                     PackageManager.VERIFICATION_REJECT,
1511                                     state.getInstallArgs().getUser());
1512                         }
1513 
1514                         Trace.asyncTraceEnd(
1515                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1516 
1517                         processPendingInstall(args, ret);
1518                         mHandler.sendEmptyMessage(MCS_UNBIND);
1519                     }
1520                     break;
1521                 }
1522                 case PACKAGE_VERIFIED: {
1523                     final int verificationId = msg.arg1;
1524 
1525                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1526                     if (state == null) {
1527                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1528                         break;
1529                     }
1530 
1531                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1532 
1533                     state.setVerifierResponse(response.callerUid, response.code);
1534 
1535                     if (state.isVerificationComplete()) {
1536                         mPendingVerification.remove(verificationId);
1537 
1538                         final InstallArgs args = state.getInstallArgs();
1539                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1540 
1541                         int ret;
1542                         if (state.isInstallAllowed()) {
1543                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1544                             broadcastPackageVerified(verificationId, originUri,
1545                                     response.code, state.getInstallArgs().getUser());
1546                             try {
1547                                 ret = args.copyApk(mContainerService, true);
1548                             } catch (RemoteException e) {
1549                                 Slog.e(TAG, "Could not contact the ContainerService");
1550                             }
1551                         } else {
1552                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1553                         }
1554 
1555                         Trace.asyncTraceEnd(
1556                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1557 
1558                         processPendingInstall(args, ret);
1559                         mHandler.sendEmptyMessage(MCS_UNBIND);
1560                     }
1561 
1562                     break;
1563                 }
1564                 case START_INTENT_FILTER_VERIFICATIONS: {
1565                     IFVerificationParams params = (IFVerificationParams) msg.obj;
1566                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1567                             params.replacing, params.pkg);
1568                     break;
1569                 }
1570                 case INTENT_FILTER_VERIFIED: {
1571                     final int verificationId = msg.arg1;
1572 
1573                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1574                             verificationId);
1575                     if (state == null) {
1576                         Slog.w(TAG, "Invalid IntentFilter verification token "
1577                                 + verificationId + " received");
1578                         break;
1579                     }
1580 
1581                     final int userId = state.getUserId();
1582 
1583                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1584                             "Processing IntentFilter verification with token:"
1585                             + verificationId + " and userId:" + userId);
1586 
1587                     final IntentFilterVerificationResponse response =
1588                             (IntentFilterVerificationResponse) msg.obj;
1589 
1590                     state.setVerifierResponse(response.callerUid, response.code);
1591 
1592                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1593                             "IntentFilter verification with token:" + verificationId
1594                             + " and userId:" + userId
1595                             + " is settings verifier response with response code:"
1596                             + response.code);
1597 
1598                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1599                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1600                                 + response.getFailedDomainsString());
1601                     }
1602 
1603                     if (state.isVerificationComplete()) {
1604                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1605                     } else {
1606                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1607                                 "IntentFilter verification with token:" + verificationId
1608                                 + " was not said to be complete");
1609                     }
1610 
1611                     break;
1612                 }
1613             }
1614         }
1615     }
1616 
handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, boolean killApp, String[] grantedPermissions, boolean launchedForRestore, String installerPackage, IPackageInstallObserver2 installObserver)1617     private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1618             boolean killApp, String[] grantedPermissions,
1619             boolean launchedForRestore, String installerPackage,
1620             IPackageInstallObserver2 installObserver) {
1621         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1622             // Send the removed broadcasts
1623             if (res.removedInfo != null) {
1624                 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1625             }
1626 
1627             // Now that we successfully installed the package, grant runtime
1628             // permissions if requested before broadcasting the install.
1629             if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion
1630                     >= Build.VERSION_CODES.M) {
1631                 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1632             }
1633 
1634             final boolean update = res.removedInfo != null
1635                     && res.removedInfo.removedPackage != null;
1636 
1637             // If this is the first time we have child packages for a disabled privileged
1638             // app that had no children, we grant requested runtime permissions to the new
1639             // children if the parent on the system image had them already granted.
1640             if (res.pkg.parentPackage != null) {
1641                 synchronized (mPackages) {
1642                     grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1643                 }
1644             }
1645 
1646             synchronized (mPackages) {
1647                 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
1648             }
1649 
1650             final String packageName = res.pkg.applicationInfo.packageName;
1651             Bundle extras = new Bundle(1);
1652             extras.putInt(Intent.EXTRA_UID, res.uid);
1653 
1654             // Determine the set of users who are adding this package for
1655             // the first time vs. those who are seeing an update.
1656             int[] firstUsers = EMPTY_INT_ARRAY;
1657             int[] updateUsers = EMPTY_INT_ARRAY;
1658             if (res.origUsers == null || res.origUsers.length == 0) {
1659                 firstUsers = res.newUsers;
1660             } else {
1661                 for (int newUser : res.newUsers) {
1662                     boolean isNew = true;
1663                     for (int origUser : res.origUsers) {
1664                         if (origUser == newUser) {
1665                             isNew = false;
1666                             break;
1667                         }
1668                     }
1669                     if (isNew) {
1670                         firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1671                     } else {
1672                         updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1673                     }
1674                 }
1675             }
1676 
1677             // Send installed broadcasts if the install/update is not ephemeral
1678             if (!isEphemeral(res.pkg)) {
1679                 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1680 
1681                 // Send added for users that see the package for the first time
1682                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1683                         extras, 0 /*flags*/, null /*targetPackage*/,
1684                         null /*finishedReceiver*/, firstUsers);
1685 
1686                 // Send added for users that don't see the package for the first time
1687                 if (update) {
1688                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
1689                 }
1690                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1691                         extras, 0 /*flags*/, null /*targetPackage*/,
1692                         null /*finishedReceiver*/, updateUsers);
1693 
1694                 // Send replaced for users that don't see the package for the first time
1695                 if (update) {
1696                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1697                             packageName, extras, 0 /*flags*/,
1698                             null /*targetPackage*/, null /*finishedReceiver*/,
1699                             updateUsers);
1700                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1701                             null /*package*/, null /*extras*/, 0 /*flags*/,
1702                             packageName /*targetPackage*/,
1703                             null /*finishedReceiver*/, updateUsers);
1704                 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1705                     // First-install and we did a restore, so we're responsible for the
1706                     // first-launch broadcast.
1707                     if (DEBUG_BACKUP) {
1708                         Slog.i(TAG, "Post-restore of " + packageName
1709                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1710                     }
1711                     sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1712                 }
1713 
1714                 // Send broadcast package appeared if forward locked/external for all users
1715                 // treat asec-hosted packages like removable media on upgrade
1716                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1717                     if (DEBUG_INSTALL) {
1718                         Slog.i(TAG, "upgrading pkg " + res.pkg
1719                                 + " is ASEC-hosted -> AVAILABLE");
1720                     }
1721                     final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1722                     ArrayList<String> pkgList = new ArrayList<>(1);
1723                     pkgList.add(packageName);
1724                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1725                 }
1726             }
1727 
1728             // Work that needs to happen on first install within each user
1729             if (firstUsers != null && firstUsers.length > 0) {
1730                 synchronized (mPackages) {
1731                     for (int userId : firstUsers) {
1732                         // If this app is a browser and it's newly-installed for some
1733                         // users, clear any default-browser state in those users. The
1734                         // app's nature doesn't depend on the user, so we can just check
1735                         // its browser nature in any user and generalize.
1736                         if (packageIsBrowser(packageName, userId)) {
1737                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1738                         }
1739 
1740                         // We may also need to apply pending (restored) runtime
1741                         // permission grants within these users.
1742                         mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1743                     }
1744                 }
1745             }
1746 
1747             // Log current value of "unknown sources" setting
1748             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1749                     getUnknownSourcesSettings());
1750 
1751             // Force a gc to clear up things
1752             Runtime.getRuntime().gc();
1753 
1754             // Remove the replaced package's older resources safely now
1755             // We delete after a gc for applications  on sdcard.
1756             if (res.removedInfo != null && res.removedInfo.args != null) {
1757                 synchronized (mInstallLock) {
1758                     res.removedInfo.args.doPostDeleteLI(true);
1759                 }
1760             }
1761         }
1762 
1763         // If someone is watching installs - notify them
1764         if (installObserver != null) {
1765             try {
1766                 Bundle extras = extrasForInstallResult(res);
1767                 installObserver.onPackageInstalled(res.name, res.returnCode,
1768                         res.returnMsg, extras);
1769             } catch (RemoteException e) {
1770                 Slog.i(TAG, "Observer no longer exists.");
1771             }
1772         }
1773     }
1774 
grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( PackageParser.Package pkg)1775     private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1776             PackageParser.Package pkg) {
1777         if (pkg.parentPackage == null) {
1778             return;
1779         }
1780         if (pkg.requestedPermissions == null) {
1781             return;
1782         }
1783         final PackageSetting disabledSysParentPs = mSettings
1784                 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1785         if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1786                 || !disabledSysParentPs.isPrivileged()
1787                 || (disabledSysParentPs.childPackageNames != null
1788                         && !disabledSysParentPs.childPackageNames.isEmpty())) {
1789             return;
1790         }
1791         final int[] allUserIds = sUserManager.getUserIds();
1792         final int permCount = pkg.requestedPermissions.size();
1793         for (int i = 0; i < permCount; i++) {
1794             String permission = pkg.requestedPermissions.get(i);
1795             BasePermission bp = mSettings.mPermissions.get(permission);
1796             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1797                 continue;
1798             }
1799             for (int userId : allUserIds) {
1800                 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1801                         permission, userId)) {
1802                     grantRuntimePermission(pkg.packageName, permission, userId);
1803                 }
1804             }
1805         }
1806     }
1807 
1808     private StorageEventListener mStorageListener = new StorageEventListener() {
1809         @Override
1810         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1811             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1812                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1813                     final String volumeUuid = vol.getFsUuid();
1814 
1815                     // Clean up any users or apps that were removed or recreated
1816                     // while this volume was missing
1817                     reconcileUsers(volumeUuid);
1818                     reconcileApps(volumeUuid);
1819 
1820                     // Clean up any install sessions that expired or were
1821                     // cancelled while this volume was missing
1822                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
1823 
1824                     loadPrivatePackages(vol);
1825 
1826                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1827                     unloadPrivatePackages(vol);
1828                 }
1829             }
1830 
1831             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1832                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1833                     updateExternalMediaStatus(true, false);
1834                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1835                     updateExternalMediaStatus(false, false);
1836                 }
1837             }
1838         }
1839 
1840         @Override
1841         public void onVolumeForgotten(String fsUuid) {
1842             if (TextUtils.isEmpty(fsUuid)) {
1843                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1844                 return;
1845             }
1846 
1847             // Remove any apps installed on the forgotten volume
1848             synchronized (mPackages) {
1849                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1850                 for (PackageSetting ps : packages) {
1851                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1852                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1853                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1854                 }
1855 
1856                 mSettings.onVolumeForgotten(fsUuid);
1857                 mSettings.writeLPr();
1858             }
1859         }
1860     };
1861 
grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions)1862     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1863             String[] grantedPermissions) {
1864         for (int userId : userIds) {
1865             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1866         }
1867 
1868         // We could have touched GID membership, so flush out packages.list
1869         synchronized (mPackages) {
1870             mSettings.writePackageListLPr();
1871         }
1872     }
1873 
grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions)1874     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1875             String[] grantedPermissions) {
1876         SettingBase sb = (SettingBase) pkg.mExtras;
1877         if (sb == null) {
1878             return;
1879         }
1880 
1881         PermissionsState permissionsState = sb.getPermissionsState();
1882 
1883         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1884                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1885 
1886         for (String permission : pkg.requestedPermissions) {
1887             final BasePermission bp;
1888             synchronized (mPackages) {
1889                 bp = mSettings.mPermissions.get(permission);
1890             }
1891             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1892                     && (grantedPermissions == null
1893                            || ArrayUtils.contains(grantedPermissions, permission))) {
1894                 final int flags = permissionsState.getPermissionFlags(permission, userId);
1895                 // Installer cannot change immutable permissions.
1896                 if ((flags & immutableFlags) == 0) {
1897                     grantRuntimePermission(pkg.packageName, permission, userId);
1898                 }
1899             }
1900         }
1901     }
1902 
extrasForInstallResult(PackageInstalledInfo res)1903     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1904         Bundle extras = null;
1905         switch (res.returnCode) {
1906             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1907                 extras = new Bundle();
1908                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1909                         res.origPermission);
1910                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1911                         res.origPackage);
1912                 break;
1913             }
1914             case PackageManager.INSTALL_SUCCEEDED: {
1915                 extras = new Bundle();
1916                 extras.putBoolean(Intent.EXTRA_REPLACING,
1917                         res.removedInfo != null && res.removedInfo.removedPackage != null);
1918                 break;
1919             }
1920         }
1921         return extras;
1922     }
1923 
scheduleWriteSettingsLocked()1924     void scheduleWriteSettingsLocked() {
1925         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1926             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1927         }
1928     }
1929 
scheduleWritePackageListLocked(int userId)1930     void scheduleWritePackageListLocked(int userId) {
1931         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
1932             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
1933             msg.arg1 = userId;
1934             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
1935         }
1936     }
1937 
scheduleWritePackageRestrictionsLocked(UserHandle user)1938     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
1939         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
1940         scheduleWritePackageRestrictionsLocked(userId);
1941     }
1942 
scheduleWritePackageRestrictionsLocked(int userId)1943     void scheduleWritePackageRestrictionsLocked(int userId) {
1944         final int[] userIds = (userId == UserHandle.USER_ALL)
1945                 ? sUserManager.getUserIds() : new int[]{userId};
1946         for (int nextUserId : userIds) {
1947             if (!sUserManager.exists(nextUserId)) return;
1948             mDirtyUsers.add(nextUserId);
1949             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1950                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1951             }
1952         }
1953     }
1954 
main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1955     public static PackageManagerService main(Context context, Installer installer,
1956             boolean factoryTest, boolean onlyCore) {
1957         // Self-check for initial settings.
1958         PackageManagerServiceCompilerMapping.checkProperties();
1959 
1960         PackageManagerService m = new PackageManagerService(context, installer,
1961                 factoryTest, onlyCore);
1962         m.enableSystemUserPackages();
1963         ServiceManager.addService("package", m);
1964         return m;
1965     }
1966 
enableSystemUserPackages()1967     private void enableSystemUserPackages() {
1968         if (!UserManager.isSplitSystemUser()) {
1969             return;
1970         }
1971         // For system user, enable apps based on the following conditions:
1972         // - app is whitelisted or belong to one of these groups:
1973         //   -- system app which has no launcher icons
1974         //   -- system app which has INTERACT_ACROSS_USERS permission
1975         //   -- system IME app
1976         // - app is not in the blacklist
1977         AppsQueryHelper queryHelper = new AppsQueryHelper(this);
1978         Set<String> enableApps = new ArraySet<>();
1979         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
1980                 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
1981                 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
1982         ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
1983         enableApps.addAll(wlApps);
1984         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
1985                 /* systemAppsOnly */ false, UserHandle.SYSTEM));
1986         ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
1987         enableApps.removeAll(blApps);
1988         Log.i(TAG, "Applications installed for system user: " + enableApps);
1989         List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
1990                 UserHandle.SYSTEM);
1991         final int allAppsSize = allAps.size();
1992         synchronized (mPackages) {
1993             for (int i = 0; i < allAppsSize; i++) {
1994                 String pName = allAps.get(i);
1995                 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
1996                 // Should not happen, but we shouldn't be failing if it does
1997                 if (pkgSetting == null) {
1998                     continue;
1999                 }
2000                 boolean install = enableApps.contains(pName);
2001                 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2002                     Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2003                             + " for system user");
2004                     pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2005                 }
2006             }
2007         }
2008     }
2009 
getDefaultDisplayMetrics(Context context, DisplayMetrics metrics)2010     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2011         DisplayManager displayManager = (DisplayManager) context.getSystemService(
2012                 Context.DISPLAY_SERVICE);
2013         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2014     }
2015 
2016     /**
2017      * Requests that files preopted on a secondary system partition be copied to the data partition
2018      * if possible.  Note that the actual copying of the files is accomplished by init for security
2019      * reasons. This simply requests that the copy takes place and awaits confirmation of its
2020      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2021      */
requestCopyPreoptedFiles()2022     private static void requestCopyPreoptedFiles() {
2023         final int WAIT_TIME_MS = 100;
2024         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2025         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2026             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2027             // We will wait for up to 100 seconds.
2028             final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000;
2029             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2030                 try {
2031                     Thread.sleep(WAIT_TIME_MS);
2032                 } catch (InterruptedException e) {
2033                     // Do nothing
2034                 }
2035                 if (SystemClock.uptimeMillis() > timeEnd) {
2036                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2037                     Slog.wtf(TAG, "cppreopt did not finish!");
2038                     break;
2039                 }
2040             }
2041         }
2042     }
2043 
PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)2044     public PackageManagerService(Context context, Installer installer,
2045             boolean factoryTest, boolean onlyCore) {
2046         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2047                 SystemClock.uptimeMillis());
2048 
2049         if (mSdkVersion <= 0) {
2050             Slog.w(TAG, "**** ro.build.version.sdk not set!");
2051         }
2052 
2053         mContext = context;
2054         mFactoryTest = factoryTest;
2055         mOnlyCore = onlyCore;
2056         mMetrics = new DisplayMetrics();
2057         mSettings = new Settings(mPackages);
2058         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2059                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2060         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2061                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2062         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2063                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2064         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2065                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2066         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2067                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2068         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2069                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2070 
2071         String separateProcesses = SystemProperties.get("debug.separate_processes");
2072         if (separateProcesses != null && separateProcesses.length() > 0) {
2073             if ("*".equals(separateProcesses)) {
2074                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2075                 mSeparateProcesses = null;
2076                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2077             } else {
2078                 mDefParseFlags = 0;
2079                 mSeparateProcesses = separateProcesses.split(",");
2080                 Slog.w(TAG, "Running with debug.separate_processes: "
2081                         + separateProcesses);
2082             }
2083         } else {
2084             mDefParseFlags = 0;
2085             mSeparateProcesses = null;
2086         }
2087 
2088         mInstaller = installer;
2089         mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2090                 "*dexopt*");
2091         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2092 
2093         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2094                 FgThread.get().getLooper());
2095 
2096         getDefaultDisplayMetrics(context, mMetrics);
2097 
2098         SystemConfig systemConfig = SystemConfig.getInstance();
2099         mGlobalGids = systemConfig.getGlobalGids();
2100         mSystemPermissions = systemConfig.getSystemPermissions();
2101         mAvailableFeatures = systemConfig.getAvailableFeatures();
2102 
2103         mProtectedPackages = new ProtectedPackages(mContext);
2104 
2105         synchronized (mInstallLock) {
2106         // writer
2107         synchronized (mPackages) {
2108             mHandlerThread = new ServiceThread(TAG,
2109                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2110             mHandlerThread.start();
2111             mHandler = new PackageHandler(mHandlerThread.getLooper());
2112             mProcessLoggingHandler = new ProcessLoggingHandler();
2113             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2114 
2115             mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2116 
2117             File dataDir = Environment.getDataDirectory();
2118             mAppInstallDir = new File(dataDir, "app");
2119             mAppLib32InstallDir = new File(dataDir, "app-lib");
2120             mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
2121             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2122             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2123 
2124             sUserManager = new UserManagerService(context, this, mPackages);
2125 
2126             // Propagate permission configuration in to package manager.
2127             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2128                     = systemConfig.getPermissions();
2129             for (int i=0; i<permConfig.size(); i++) {
2130                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2131                 BasePermission bp = mSettings.mPermissions.get(perm.name);
2132                 if (bp == null) {
2133                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2134                     mSettings.mPermissions.put(perm.name, bp);
2135                 }
2136                 if (perm.gids != null) {
2137                     bp.setGids(perm.gids, perm.perUser);
2138                 }
2139             }
2140 
2141             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2142             for (int i=0; i<libConfig.size(); i++) {
2143                 mSharedLibraries.put(libConfig.keyAt(i),
2144                         new SharedLibraryEntry(libConfig.valueAt(i), null));
2145             }
2146 
2147             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2148 
2149             mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2150 
2151             if (mFirstBoot) {
2152                 requestCopyPreoptedFiles();
2153             }
2154 
2155             String customResolverActivity = Resources.getSystem().getString(
2156                     R.string.config_customResolverActivity);
2157             if (TextUtils.isEmpty(customResolverActivity)) {
2158                 customResolverActivity = null;
2159             } else {
2160                 mCustomResolverComponentName = ComponentName.unflattenFromString(
2161                         customResolverActivity);
2162             }
2163 
2164             long startTime = SystemClock.uptimeMillis();
2165 
2166             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2167                     startTime);
2168 
2169             // Set flag to monitor and not change apk file paths when
2170             // scanning install directories.
2171             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
2172 
2173             final String bootClassPath = System.getenv("BOOTCLASSPATH");
2174             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2175 
2176             if (bootClassPath == null) {
2177                 Slog.w(TAG, "No BOOTCLASSPATH found!");
2178             }
2179 
2180             if (systemServerClassPath == null) {
2181                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2182             }
2183 
2184             final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2185             final String[] dexCodeInstructionSets =
2186                     getDexCodeInstructionSets(
2187                             allInstructionSets.toArray(new String[allInstructionSets.size()]));
2188 
2189             /**
2190              * Ensure all external libraries have had dexopt run on them.
2191              */
2192             if (mSharedLibraries.size() > 0) {
2193                 // NOTE: For now, we're compiling these system "shared libraries"
2194                 // (and framework jars) into all available architectures. It's possible
2195                 // to compile them only when we come across an app that uses them (there's
2196                 // already logic for that in scanPackageLI) but that adds some complexity.
2197                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2198                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
2199                         final String lib = libEntry.path;
2200                         if (lib == null) {
2201                             continue;
2202                         }
2203 
2204                         try {
2205                             // Shared libraries do not have profiles so we perform a full
2206                             // AOT compilation (if needed).
2207                             int dexoptNeeded = DexFile.getDexOptNeeded(
2208                                     lib, dexCodeInstructionSet,
2209                                     getCompilerFilterForReason(REASON_SHARED_APK),
2210                                     false /* newProfile */);
2211                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2212                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
2213                                         dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
2214                                         getCompilerFilterForReason(REASON_SHARED_APK),
2215                                         StorageManager.UUID_PRIVATE_INTERNAL,
2216                                         SKIP_SHARED_LIBRARY_CHECK);
2217                             }
2218                         } catch (FileNotFoundException e) {
2219                             Slog.w(TAG, "Library not found: " + lib);
2220                         } catch (IOException | InstallerException e) {
2221                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
2222                                     + e.getMessage());
2223                         }
2224                     }
2225                 }
2226             }
2227 
2228             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2229 
2230             final VersionInfo ver = mSettings.getInternalVersion();
2231             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2232 
2233             // when upgrading from pre-M, promote system app permissions from install to runtime
2234             mPromoteSystemApps =
2235                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2236 
2237             // When upgrading from pre-N, we need to handle package extraction like first boot,
2238             // as there is no profiling data available.
2239             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2240 
2241             // save off the names of pre-existing system packages prior to scanning; we don't
2242             // want to automatically grant runtime permissions for new system apps
2243             if (mPromoteSystemApps) {
2244                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2245                 while (pkgSettingIter.hasNext()) {
2246                     PackageSetting ps = pkgSettingIter.next();
2247                     if (isSystemApp(ps)) {
2248                         mExistingSystemPackages.add(ps.name);
2249                     }
2250                 }
2251             }
2252 
2253             // Collect vendor overlay packages.
2254             // (Do this before scanning any apps.)
2255             // For security and version matching reason, only consider
2256             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
2257             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
2258             scanDirTracedLI(vendorOverlayDir, mDefParseFlags
2259                     | PackageParser.PARSE_IS_SYSTEM
2260                     | PackageParser.PARSE_IS_SYSTEM_DIR
2261                     | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2262 
2263             // Find base frameworks (resource packages without code).
2264             scanDirTracedLI(frameworkDir, mDefParseFlags
2265                     | PackageParser.PARSE_IS_SYSTEM
2266                     | PackageParser.PARSE_IS_SYSTEM_DIR
2267                     | PackageParser.PARSE_IS_PRIVILEGED,
2268                     scanFlags | SCAN_NO_DEX, 0);
2269 
2270             // Collected privileged system packages.
2271             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2272             scanDirTracedLI(privilegedAppDir, mDefParseFlags
2273                     | PackageParser.PARSE_IS_SYSTEM
2274                     | PackageParser.PARSE_IS_SYSTEM_DIR
2275                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2276 
2277             // Collect ordinary system packages.
2278             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2279             scanDirTracedLI(systemAppDir, mDefParseFlags
2280                     | PackageParser.PARSE_IS_SYSTEM
2281                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2282 
2283             // Collect all vendor packages.
2284             File vendorAppDir = new File("/vendor/app");
2285             try {
2286                 vendorAppDir = vendorAppDir.getCanonicalFile();
2287             } catch (IOException e) {
2288                 // failed to look up canonical path, continue with original one
2289             }
2290             scanDirTracedLI(vendorAppDir, mDefParseFlags
2291                     | PackageParser.PARSE_IS_SYSTEM
2292                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2293 
2294             // Collect all OEM packages.
2295             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2296             scanDirTracedLI(oemAppDir, mDefParseFlags
2297                     | PackageParser.PARSE_IS_SYSTEM
2298                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2299 
2300             // Prune any system packages that no longer exist.
2301             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2302             if (!mOnlyCore) {
2303                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2304                 while (psit.hasNext()) {
2305                     PackageSetting ps = psit.next();
2306 
2307                     /*
2308                      * If this is not a system app, it can't be a
2309                      * disable system app.
2310                      */
2311                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2312                         continue;
2313                     }
2314 
2315                     /*
2316                      * If the package is scanned, it's not erased.
2317                      */
2318                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2319                     if (scannedPkg != null) {
2320                         /*
2321                          * If the system app is both scanned and in the
2322                          * disabled packages list, then it must have been
2323                          * added via OTA. Remove it from the currently
2324                          * scanned package so the previously user-installed
2325                          * application can be scanned.
2326                          */
2327                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2328                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2329                                     + ps.name + "; removing system app.  Last known codePath="
2330                                     + ps.codePathString + ", installStatus=" + ps.installStatus
2331                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2332                                     + scannedPkg.mVersionCode);
2333                             removePackageLI(scannedPkg, true);
2334                             mExpectingBetter.put(ps.name, ps.codePath);
2335                         }
2336 
2337                         continue;
2338                     }
2339 
2340                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2341                         psit.remove();
2342                         logCriticalInfo(Log.WARN, "System package " + ps.name
2343                                 + " no longer exists; it's data will be wiped");
2344                         // Actual deletion of code and data will be handled by later
2345                         // reconciliation step
2346                     } else {
2347                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2348                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2349                             possiblyDeletedUpdatedSystemApps.add(ps.name);
2350                         }
2351                     }
2352                 }
2353             }
2354 
2355             //look for any incomplete package installations
2356             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2357             for (int i = 0; i < deletePkgsList.size(); i++) {
2358                 // Actual deletion of code and data will be handled by later
2359                 // reconciliation step
2360                 final String packageName = deletePkgsList.get(i).name;
2361                 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2362                 synchronized (mPackages) {
2363                     mSettings.removePackageLPw(packageName);
2364                 }
2365             }
2366 
2367             //delete tmp files
2368             deleteTempPackageFiles();
2369 
2370             // Remove any shared userIDs that have no associated packages
2371             mSettings.pruneSharedUsersLPw();
2372 
2373             if (!mOnlyCore) {
2374                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2375                         SystemClock.uptimeMillis());
2376                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2377 
2378                 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2379                         | PackageParser.PARSE_FORWARD_LOCK,
2380                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2381 
2382                 scanDirLI(mEphemeralInstallDir, mDefParseFlags
2383                         | PackageParser.PARSE_IS_EPHEMERAL,
2384                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2385 
2386                 /**
2387                  * Remove disable package settings for any updated system
2388                  * apps that were removed via an OTA. If they're not a
2389                  * previously-updated app, remove them completely.
2390                  * Otherwise, just revoke their system-level permissions.
2391                  */
2392                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2393                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2394                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2395 
2396                     String msg;
2397                     if (deletedPkg == null) {
2398                         msg = "Updated system package " + deletedAppName
2399                                 + " no longer exists; it's data will be wiped";
2400                         // Actual deletion of code and data will be handled by later
2401                         // reconciliation step
2402                     } else {
2403                         msg = "Updated system app + " + deletedAppName
2404                                 + " no longer present; removing system privileges for "
2405                                 + deletedAppName;
2406 
2407                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2408 
2409                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2410                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2411                     }
2412                     logCriticalInfo(Log.WARN, msg);
2413                 }
2414 
2415                 /**
2416                  * Make sure all system apps that we expected to appear on
2417                  * the userdata partition actually showed up. If they never
2418                  * appeared, crawl back and revive the system version.
2419                  */
2420                 for (int i = 0; i < mExpectingBetter.size(); i++) {
2421                     final String packageName = mExpectingBetter.keyAt(i);
2422                     if (!mPackages.containsKey(packageName)) {
2423                         final File scanFile = mExpectingBetter.valueAt(i);
2424 
2425                         logCriticalInfo(Log.WARN, "Expected better " + packageName
2426                                 + " but never showed up; reverting to system");
2427 
2428                         int reparseFlags = mDefParseFlags;
2429                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
2430                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2431                                     | PackageParser.PARSE_IS_SYSTEM_DIR
2432                                     | PackageParser.PARSE_IS_PRIVILEGED;
2433                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
2434                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2435                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2436                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2437                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2438                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2439                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
2440                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2441                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2442                         } else {
2443                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2444                             continue;
2445                         }
2446 
2447                         mSettings.enableSystemPackageLPw(packageName);
2448 
2449                         try {
2450                             scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2451                         } catch (PackageManagerException e) {
2452                             Slog.e(TAG, "Failed to parse original system package: "
2453                                     + e.getMessage());
2454                         }
2455                     }
2456                 }
2457             }
2458             mExpectingBetter.clear();
2459 
2460             // Resolve protected action filters. Only the setup wizard is allowed to
2461             // have a high priority filter for these actions.
2462             mSetupWizardPackage = getSetupWizardPackageName();
2463             if (mProtectedFilters.size() > 0) {
2464                 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2465                     Slog.i(TAG, "No setup wizard;"
2466                         + " All protected intents capped to priority 0");
2467                 }
2468                 for (ActivityIntentInfo filter : mProtectedFilters) {
2469                     if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2470                         if (DEBUG_FILTERS) {
2471                             Slog.i(TAG, "Found setup wizard;"
2472                                 + " allow priority " + filter.getPriority() + ";"
2473                                 + " package: " + filter.activity.info.packageName
2474                                 + " activity: " + filter.activity.className
2475                                 + " priority: " + filter.getPriority());
2476                         }
2477                         // skip setup wizard; allow it to keep the high priority filter
2478                         continue;
2479                     }
2480                     Slog.w(TAG, "Protected action; cap priority to 0;"
2481                             + " package: " + filter.activity.info.packageName
2482                             + " activity: " + filter.activity.className
2483                             + " origPrio: " + filter.getPriority());
2484                     filter.setPriority(0);
2485                 }
2486             }
2487             mDeferProtectedFilters = false;
2488             mProtectedFilters.clear();
2489 
2490             // Now that we know all of the shared libraries, update all clients to have
2491             // the correct library paths.
2492             updateAllSharedLibrariesLPw();
2493 
2494             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2495                 // NOTE: We ignore potential failures here during a system scan (like
2496                 // the rest of the commands above) because there's precious little we
2497                 // can do about it. A settings error is reported, though.
2498                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2499                         false /* boot complete */);
2500             }
2501 
2502             // Now that we know all the packages we are keeping,
2503             // read and update their last usage times.
2504             mPackageUsage.read(mPackages);
2505             mCompilerStats.read();
2506 
2507             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2508                     SystemClock.uptimeMillis());
2509             Slog.i(TAG, "Time to scan packages: "
2510                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
2511                     + " seconds");
2512 
2513             // If the platform SDK has changed since the last time we booted,
2514             // we need to re-grant app permission to catch any new ones that
2515             // appear.  This is really a hack, and means that apps can in some
2516             // cases get permissions that the user didn't initially explicitly
2517             // allow...  it would be nice to have some better way to handle
2518             // this situation.
2519             int updateFlags = UPDATE_PERMISSIONS_ALL;
2520             if (ver.sdkVersion != mSdkVersion) {
2521                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2522                         + mSdkVersion + "; regranting permissions for internal storage");
2523                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2524             }
2525             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2526             ver.sdkVersion = mSdkVersion;
2527 
2528             // If this is the first boot or an update from pre-M, and it is a normal
2529             // boot, then we need to initialize the default preferred apps across
2530             // all defined users.
2531             if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2532                 for (UserInfo user : sUserManager.getUsers(true)) {
2533                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2534                     applyFactoryDefaultBrowserLPw(user.id);
2535                     primeDomainVerificationsLPw(user.id);
2536                 }
2537             }
2538 
2539             // Prepare storage for system user really early during boot,
2540             // since core system apps like SettingsProvider and SystemUI
2541             // can't wait for user to start
2542             final int storageFlags;
2543             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2544                 storageFlags = StorageManager.FLAG_STORAGE_DE;
2545             } else {
2546                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2547             }
2548             reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
2549                     storageFlags);
2550 
2551             // If this is first boot after an OTA, and a normal boot, then
2552             // we need to clear code cache directories.
2553             // Note that we do *not* clear the application profiles. These remain valid
2554             // across OTAs and are used to drive profile verification (post OTA) and
2555             // profile compilation (without waiting to collect a fresh set of profiles).
2556             if (mIsUpgrade && !onlyCore) {
2557                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2558                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2559                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
2560                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2561                         // No apps are running this early, so no need to freeze
2562                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2563                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2564                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2565                     }
2566                 }
2567                 ver.fingerprint = Build.FINGERPRINT;
2568             }
2569 
2570             checkDefaultBrowser();
2571 
2572             // clear only after permissions and other defaults have been updated
2573             mExistingSystemPackages.clear();
2574             mPromoteSystemApps = false;
2575 
2576             // All the changes are done during package scanning.
2577             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2578 
2579             // can downgrade to reader
2580             mSettings.writeLPr();
2581 
2582             // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
2583             // early on (before the package manager declares itself as early) because other
2584             // components in the system server might ask for package contexts for these apps.
2585             //
2586             // Note that "onlyCore" in this context means the system is encrypted or encrypting
2587             // (i.e, that the data partition is unavailable).
2588             if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
2589                 long start = System.nanoTime();
2590                 List<PackageParser.Package> coreApps = new ArrayList<>();
2591                 for (PackageParser.Package pkg : mPackages.values()) {
2592                     if (pkg.coreApp) {
2593                         coreApps.add(pkg);
2594                     }
2595                 }
2596 
2597                 int[] stats = performDexOptUpgrade(coreApps, false,
2598                         getCompilerFilterForReason(REASON_CORE_APP));
2599 
2600                 final int elapsedTimeSeconds =
2601                         (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
2602                 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
2603 
2604                 if (DEBUG_DEXOPT) {
2605                     Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
2606                             stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
2607                 }
2608 
2609 
2610                 // TODO: Should we log these stats to tron too ?
2611                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
2612                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
2613                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
2614                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
2615             }
2616 
2617             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2618                     SystemClock.uptimeMillis());
2619 
2620             if (!mOnlyCore) {
2621                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2622                 mRequiredInstallerPackage = getRequiredInstallerLPr();
2623                 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2624                 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2625                         mIntentFilterVerifierComponent);
2626                 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2627                         PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
2628                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2629                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
2630             } else {
2631                 mRequiredVerifierPackage = null;
2632                 mRequiredInstallerPackage = null;
2633                 mIntentFilterVerifierComponent = null;
2634                 mIntentFilterVerifier = null;
2635                 mServicesSystemSharedLibraryPackageName = null;
2636                 mSharedSystemSharedLibraryPackageName = null;
2637             }
2638 
2639             mInstallerService = new PackageInstallerService(context, this);
2640 
2641             final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2642             final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
2643             // both the installer and resolver must be present to enable ephemeral
2644             if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
2645                 if (DEBUG_EPHEMERAL) {
2646                     Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
2647                             + " installer:" + ephemeralInstallerComponent);
2648                 }
2649                 mEphemeralResolverComponent = ephemeralResolverComponent;
2650                 mEphemeralInstallerComponent = ephemeralInstallerComponent;
2651                 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2652                 mEphemeralResolverConnection =
2653                         new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
2654             } else {
2655                 if (DEBUG_EPHEMERAL) {
2656                     final String missingComponent =
2657                             (ephemeralResolverComponent == null)
2658                             ? (ephemeralInstallerComponent == null)
2659                                     ? "resolver and installer"
2660                                     : "resolver"
2661                             : "installer";
2662                     Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
2663                 }
2664                 mEphemeralResolverComponent = null;
2665                 mEphemeralInstallerComponent = null;
2666                 mEphemeralResolverConnection = null;
2667             }
2668 
2669             mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
2670         } // synchronized (mPackages)
2671         } // synchronized (mInstallLock)
2672 
2673         // Now after opening every single application zip, make sure they
2674         // are all flushed.  Not really needed, but keeps things nice and
2675         // tidy.
2676         Runtime.getRuntime().gc();
2677 
2678         // The initial scanning above does many calls into installd while
2679         // holding the mPackages lock, but we're mostly interested in yelling
2680         // once we have a booted system.
2681         mInstaller.setWarnIfHeld(mPackages);
2682 
2683         // Expose private service for system components to use.
2684         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2685     }
2686 
2687     @Override
2688     public boolean isFirstBoot() {
2689         return mFirstBoot;
2690     }
2691 
2692     @Override
2693     public boolean isOnlyCoreApps() {
2694         return mOnlyCore;
2695     }
2696 
2697     @Override
2698     public boolean isUpgrade() {
2699         return mIsUpgrade;
2700     }
2701 
2702     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2703         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2704 
2705         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2706                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2707                 UserHandle.USER_SYSTEM);
2708         if (matches.size() == 1) {
2709             return matches.get(0).getComponentInfo().packageName;
2710         } else {
2711             Log.e(TAG, "There should probably be exactly one verifier; found " + matches);
2712             return null;
2713         }
2714     }
2715 
2716     private @NonNull String getRequiredSharedLibraryLPr(String libraryName) {
2717         synchronized (mPackages) {
2718             SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName);
2719             if (libraryEntry == null) {
2720                 throw new IllegalStateException("Missing required shared library:" + libraryName);
2721             }
2722             return libraryEntry.apk;
2723         }
2724     }
2725 
2726     private @NonNull String getRequiredInstallerLPr() {
2727         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2728         intent.addCategory(Intent.CATEGORY_DEFAULT);
2729         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2730 
2731         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2732                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2733                 UserHandle.USER_SYSTEM);
2734         if (matches.size() == 1) {
2735             ResolveInfo resolveInfo = matches.get(0);
2736             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
2737                 throw new RuntimeException("The installer must be a privileged app");
2738             }
2739             return matches.get(0).getComponentInfo().packageName;
2740         } else {
2741             throw new RuntimeException("There must be exactly one installer; found " + matches);
2742         }
2743     }
2744 
2745     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2746         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2747 
2748         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2749                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2750                 UserHandle.USER_SYSTEM);
2751         ResolveInfo best = null;
2752         final int N = matches.size();
2753         for (int i = 0; i < N; i++) {
2754             final ResolveInfo cur = matches.get(i);
2755             final String packageName = cur.getComponentInfo().packageName;
2756             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2757                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2758                 continue;
2759             }
2760 
2761             if (best == null || cur.priority > best.priority) {
2762                 best = cur;
2763             }
2764         }
2765 
2766         if (best != null) {
2767             return best.getComponentInfo().getComponentName();
2768         } else {
2769             throw new RuntimeException("There must be at least one intent filter verifier");
2770         }
2771     }
2772 
2773     private @Nullable ComponentName getEphemeralResolverLPr() {
2774         final String[] packageArray =
2775                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2776         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
2777             if (DEBUG_EPHEMERAL) {
2778                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2779             }
2780             return null;
2781         }
2782 
2783         final int resolveFlags =
2784                 MATCH_DIRECT_BOOT_AWARE
2785                 | MATCH_DIRECT_BOOT_UNAWARE
2786                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2787         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2788         final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
2789                 resolveFlags, UserHandle.USER_SYSTEM);
2790 
2791         final int N = resolvers.size();
2792         if (N == 0) {
2793             if (DEBUG_EPHEMERAL) {
2794                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2795             }
2796             return null;
2797         }
2798 
2799         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2800         for (int i = 0; i < N; i++) {
2801             final ResolveInfo info = resolvers.get(i);
2802 
2803             if (info.serviceInfo == null) {
2804                 continue;
2805             }
2806 
2807             final String packageName = info.serviceInfo.packageName;
2808             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
2809                 if (DEBUG_EPHEMERAL) {
2810                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2811                             + " pkg: " + packageName + ", info:" + info);
2812                 }
2813                 continue;
2814             }
2815 
2816             if (DEBUG_EPHEMERAL) {
2817                 Slog.v(TAG, "Ephemeral resolver found;"
2818                         + " pkg: " + packageName + ", info:" + info);
2819             }
2820             return new ComponentName(packageName, info.serviceInfo.name);
2821         }
2822         if (DEBUG_EPHEMERAL) {
2823             Slog.v(TAG, "Ephemeral resolver NOT found");
2824         }
2825         return null;
2826     }
2827 
2828     private @Nullable ComponentName getEphemeralInstallerLPr() {
2829         final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2830         intent.addCategory(Intent.CATEGORY_DEFAULT);
2831         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2832 
2833         final int resolveFlags =
2834                 MATCH_DIRECT_BOOT_AWARE
2835                 | MATCH_DIRECT_BOOT_UNAWARE
2836                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2837         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2838                 resolveFlags, UserHandle.USER_SYSTEM);
2839         if (matches.size() == 0) {
2840             return null;
2841         } else if (matches.size() == 1) {
2842             return matches.get(0).getComponentInfo().getComponentName();
2843         } else {
2844             throw new RuntimeException(
2845                     "There must be at most one ephemeral installer; found " + matches);
2846         }
2847     }
2848 
2849     private void primeDomainVerificationsLPw(int userId) {
2850         if (DEBUG_DOMAIN_VERIFICATION) {
2851             Slog.d(TAG, "Priming domain verifications in user " + userId);
2852         }
2853 
2854         SystemConfig systemConfig = SystemConfig.getInstance();
2855         ArraySet<String> packages = systemConfig.getLinkedApps();
2856         ArraySet<String> domains = new ArraySet<String>();
2857 
2858         for (String packageName : packages) {
2859             PackageParser.Package pkg = mPackages.get(packageName);
2860             if (pkg != null) {
2861                 if (!pkg.isSystemApp()) {
2862                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2863                     continue;
2864                 }
2865 
2866                 domains.clear();
2867                 for (PackageParser.Activity a : pkg.activities) {
2868                     for (ActivityIntentInfo filter : a.intents) {
2869                         if (hasValidDomains(filter)) {
2870                             domains.addAll(filter.getHostsList());
2871                         }
2872                     }
2873                 }
2874 
2875                 if (domains.size() > 0) {
2876                     if (DEBUG_DOMAIN_VERIFICATION) {
2877                         Slog.v(TAG, "      + " + packageName);
2878                     }
2879                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2880                     // state w.r.t. the formal app-linkage "no verification attempted" state;
2881                     // and then 'always' in the per-user state actually used for intent resolution.
2882                     final IntentFilterVerificationInfo ivi;
2883                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2884                             new ArrayList<String>(domains));
2885                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2886                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2887                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2888                 } else {
2889                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2890                             + "' does not handle web links");
2891                 }
2892             } else {
2893                 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2894             }
2895         }
2896 
2897         scheduleWritePackageRestrictionsLocked(userId);
2898         scheduleWriteSettingsLocked();
2899     }
2900 
2901     private void applyFactoryDefaultBrowserLPw(int userId) {
2902         // The default browser app's package name is stored in a string resource,
2903         // with a product-specific overlay used for vendor customization.
2904         String browserPkg = mContext.getResources().getString(
2905                 com.android.internal.R.string.default_browser);
2906         if (!TextUtils.isEmpty(browserPkg)) {
2907             // non-empty string => required to be a known package
2908             PackageSetting ps = mSettings.mPackages.get(browserPkg);
2909             if (ps == null) {
2910                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2911                 browserPkg = null;
2912             } else {
2913                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2914             }
2915         }
2916 
2917         // Nothing valid explicitly set? Make the factory-installed browser the explicit
2918         // default.  If there's more than one, just leave everything alone.
2919         if (browserPkg == null) {
2920             calculateDefaultBrowserLPw(userId);
2921         }
2922     }
2923 
2924     private void calculateDefaultBrowserLPw(int userId) {
2925         List<String> allBrowsers = resolveAllBrowserApps(userId);
2926         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2927         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2928     }
2929 
2930     private List<String> resolveAllBrowserApps(int userId) {
2931         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2932         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
2933                 PackageManager.MATCH_ALL, userId);
2934 
2935         final int count = list.size();
2936         List<String> result = new ArrayList<String>(count);
2937         for (int i=0; i<count; i++) {
2938             ResolveInfo info = list.get(i);
2939             if (info.activityInfo == null
2940                     || !info.handleAllWebDataURI
2941                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2942                     || result.contains(info.activityInfo.packageName)) {
2943                 continue;
2944             }
2945             result.add(info.activityInfo.packageName);
2946         }
2947 
2948         return result;
2949     }
2950 
2951     private boolean packageIsBrowser(String packageName, int userId) {
2952         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
2953                 PackageManager.MATCH_ALL, userId);
2954         final int N = list.size();
2955         for (int i = 0; i < N; i++) {
2956             ResolveInfo info = list.get(i);
2957             if (packageName.equals(info.activityInfo.packageName)) {
2958                 return true;
2959             }
2960         }
2961         return false;
2962     }
2963 
2964     private void checkDefaultBrowser() {
2965         final int myUserId = UserHandle.myUserId();
2966         final String packageName = getDefaultBrowserPackageName(myUserId);
2967         if (packageName != null) {
2968             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2969             if (info == null) {
2970                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
2971                 synchronized (mPackages) {
2972                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
2973                 }
2974             }
2975         }
2976     }
2977 
2978     @Override
2979     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2980             throws RemoteException {
2981         try {
2982             return super.onTransact(code, data, reply, flags);
2983         } catch (RuntimeException e) {
2984             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2985                 Slog.wtf(TAG, "Package Manager Crash", e);
2986             }
2987             throw e;
2988         }
2989     }
2990 
2991     static int[] appendInts(int[] cur, int[] add) {
2992         if (add == null) return cur;
2993         if (cur == null) return add;
2994         final int N = add.length;
2995         for (int i=0; i<N; i++) {
2996             cur = appendInt(cur, add[i]);
2997         }
2998         return cur;
2999     }
3000 
3001     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3002         if (!sUserManager.exists(userId)) return null;
3003         if (ps == null) {
3004             return null;
3005         }
3006         final PackageParser.Package p = ps.pkg;
3007         if (p == null) {
3008             return null;
3009         }
3010 
3011         final PermissionsState permissionsState = ps.getPermissionsState();
3012 
3013         // Compute GIDs only if requested
3014         final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3015                 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3016         // Compute granted permissions only if package has requested permissions
3017         final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3018                 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3019         final PackageUserState state = ps.readUserState(userId);
3020 
3021         return PackageParser.generatePackageInfo(p, gids, flags,
3022                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3023     }
3024 
3025     @Override
3026     public void checkPackageStartable(String packageName, int userId) {
3027         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3028 
3029         synchronized (mPackages) {
3030             final PackageSetting ps = mSettings.mPackages.get(packageName);
3031             if (ps == null) {
3032                 throw new SecurityException("Package " + packageName + " was not found!");
3033             }
3034 
3035             if (!ps.getInstalled(userId)) {
3036                 throw new SecurityException(
3037                         "Package " + packageName + " was not installed for user " + userId + "!");
3038             }
3039 
3040             if (mSafeMode && !ps.isSystem()) {
3041                 throw new SecurityException("Package " + packageName + " not a system app!");
3042             }
3043 
3044             if (mFrozenPackages.contains(packageName)) {
3045                 throw new SecurityException("Package " + packageName + " is currently frozen!");
3046             }
3047 
3048             if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3049                     || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3050                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3051             }
3052         }
3053     }
3054 
3055     @Override
3056     public boolean isPackageAvailable(String packageName, int userId) {
3057         if (!sUserManager.exists(userId)) return false;
3058         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3059                 false /* requireFullPermission */, false /* checkShell */, "is package available");
3060         synchronized (mPackages) {
3061             PackageParser.Package p = mPackages.get(packageName);
3062             if (p != null) {
3063                 final PackageSetting ps = (PackageSetting) p.mExtras;
3064                 if (ps != null) {
3065                     final PackageUserState state = ps.readUserState(userId);
3066                     if (state != null) {
3067                         return PackageParser.isAvailable(state);
3068                     }
3069                 }
3070             }
3071         }
3072         return false;
3073     }
3074 
3075     @Override
3076     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3077         if (!sUserManager.exists(userId)) return null;
3078         flags = updateFlagsForPackage(flags, userId, packageName);
3079         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3080                 false /* requireFullPermission */, false /* checkShell */, "get package info");
3081         // reader
3082         synchronized (mPackages) {
3083             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3084             PackageParser.Package p = null;
3085             if (matchFactoryOnly) {
3086                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3087                 if (ps != null) {
3088                     return generatePackageInfo(ps, flags, userId);
3089                 }
3090             }
3091             if (p == null) {
3092                 p = mPackages.get(packageName);
3093                 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3094                     return null;
3095                 }
3096             }
3097             if (DEBUG_PACKAGE_INFO)
3098                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3099             if (p != null) {
3100                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3101             }
3102             if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3103                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3104                 return generatePackageInfo(ps, flags, userId);
3105             }
3106         }
3107         return null;
3108     }
3109 
3110     @Override
3111     public String[] currentToCanonicalPackageNames(String[] names) {
3112         String[] out = new String[names.length];
3113         // reader
3114         synchronized (mPackages) {
3115             for (int i=names.length-1; i>=0; i--) {
3116                 PackageSetting ps = mSettings.mPackages.get(names[i]);
3117                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3118             }
3119         }
3120         return out;
3121     }
3122 
3123     @Override
3124     public String[] canonicalToCurrentPackageNames(String[] names) {
3125         String[] out = new String[names.length];
3126         // reader
3127         synchronized (mPackages) {
3128             for (int i=names.length-1; i>=0; i--) {
3129                 String cur = mSettings.mRenamedPackages.get(names[i]);
3130                 out[i] = cur != null ? cur : names[i];
3131             }
3132         }
3133         return out;
3134     }
3135 
3136     @Override
3137     public int getPackageUid(String packageName, int flags, int userId) {
3138         if (!sUserManager.exists(userId)) return -1;
3139         flags = updateFlagsForPackage(flags, userId, packageName);
3140         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3141                 false /* requireFullPermission */, false /* checkShell */, "get package uid");
3142 
3143         // reader
3144         synchronized (mPackages) {
3145             final PackageParser.Package p = mPackages.get(packageName);
3146             if (p != null && p.isMatch(flags)) {
3147                 return UserHandle.getUid(userId, p.applicationInfo.uid);
3148             }
3149             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3150                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3151                 if (ps != null && ps.isMatch(flags)) {
3152                     return UserHandle.getUid(userId, ps.appId);
3153                 }
3154             }
3155         }
3156 
3157         return -1;
3158     }
3159 
3160     @Override
3161     public int[] getPackageGids(String packageName, int flags, int userId) {
3162         if (!sUserManager.exists(userId)) return null;
3163         flags = updateFlagsForPackage(flags, userId, packageName);
3164         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3165                 false /* requireFullPermission */, false /* checkShell */,
3166                 "getPackageGids");
3167 
3168         // reader
3169         synchronized (mPackages) {
3170             final PackageParser.Package p = mPackages.get(packageName);
3171             if (p != null && p.isMatch(flags)) {
3172                 PackageSetting ps = (PackageSetting) p.mExtras;
3173                 return ps.getPermissionsState().computeGids(userId);
3174             }
3175             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3176                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3177                 if (ps != null && ps.isMatch(flags)) {
3178                     return ps.getPermissionsState().computeGids(userId);
3179                 }
3180             }
3181         }
3182 
3183         return null;
3184     }
3185 
3186     static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3187         if (bp.perm != null) {
3188             return PackageParser.generatePermissionInfo(bp.perm, flags);
3189         }
3190         PermissionInfo pi = new PermissionInfo();
3191         pi.name = bp.name;
3192         pi.packageName = bp.sourcePackage;
3193         pi.nonLocalizedLabel = bp.name;
3194         pi.protectionLevel = bp.protectionLevel;
3195         return pi;
3196     }
3197 
3198     @Override
3199     public PermissionInfo getPermissionInfo(String name, int flags) {
3200         // reader
3201         synchronized (mPackages) {
3202             final BasePermission p = mSettings.mPermissions.get(name);
3203             if (p != null) {
3204                 return generatePermissionInfo(p, flags);
3205             }
3206             return null;
3207         }
3208     }
3209 
3210     @Override
3211     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3212             int flags) {
3213         // reader
3214         synchronized (mPackages) {
3215             if (group != null && !mPermissionGroups.containsKey(group)) {
3216                 // This is thrown as NameNotFoundException
3217                 return null;
3218             }
3219 
3220             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3221             for (BasePermission p : mSettings.mPermissions.values()) {
3222                 if (group == null) {
3223                     if (p.perm == null || p.perm.info.group == null) {
3224                         out.add(generatePermissionInfo(p, flags));
3225                     }
3226                 } else {
3227                     if (p.perm != null && group.equals(p.perm.info.group)) {
3228                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3229                     }
3230                 }
3231             }
3232             return new ParceledListSlice<>(out);
3233         }
3234     }
3235 
3236     @Override
3237     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3238         // reader
3239         synchronized (mPackages) {
3240             return PackageParser.generatePermissionGroupInfo(
3241                     mPermissionGroups.get(name), flags);
3242         }
3243     }
3244 
3245     @Override
3246     public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3247         // reader
3248         synchronized (mPackages) {
3249             final int N = mPermissionGroups.size();
3250             ArrayList<PermissionGroupInfo> out
3251                     = new ArrayList<PermissionGroupInfo>(N);
3252             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3253                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3254             }
3255             return new ParceledListSlice<>(out);
3256         }
3257     }
3258 
3259     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3260             int userId) {
3261         if (!sUserManager.exists(userId)) return null;
3262         PackageSetting ps = mSettings.mPackages.get(packageName);
3263         if (ps != null) {
3264             if (ps.pkg == null) {
3265                 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3266                 if (pInfo != null) {
3267                     return pInfo.applicationInfo;
3268                 }
3269                 return null;
3270             }
3271             return PackageParser.generateApplicationInfo(ps.pkg, flags,
3272                     ps.readUserState(userId), userId);
3273         }
3274         return null;
3275     }
3276 
3277     @Override
3278     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3279         if (!sUserManager.exists(userId)) return null;
3280         flags = updateFlagsForApplication(flags, userId, packageName);
3281         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3282                 false /* requireFullPermission */, false /* checkShell */, "get application info");
3283         // writer
3284         synchronized (mPackages) {
3285             PackageParser.Package p = mPackages.get(packageName);
3286             if (DEBUG_PACKAGE_INFO) Log.v(
3287                     TAG, "getApplicationInfo " + packageName
3288                     + ": " + p);
3289             if (p != null) {
3290                 PackageSetting ps = mSettings.mPackages.get(packageName);
3291                 if (ps == null) return null;
3292                 // Note: isEnabledLP() does not apply here - always return info
3293                 return PackageParser.generateApplicationInfo(
3294                         p, flags, ps.readUserState(userId), userId);
3295             }
3296             if ("android".equals(packageName)||"system".equals(packageName)) {
3297                 return mAndroidApplication;
3298             }
3299             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3300                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3301             }
3302         }
3303         return null;
3304     }
3305 
3306     @Override
3307     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3308             final IPackageDataObserver observer) {
3309         mContext.enforceCallingOrSelfPermission(
3310                 android.Manifest.permission.CLEAR_APP_CACHE, null);
3311         // Queue up an async operation since clearing cache may take a little while.
3312         mHandler.post(new Runnable() {
3313             public void run() {
3314                 mHandler.removeCallbacks(this);
3315                 boolean success = true;
3316                 synchronized (mInstallLock) {
3317                     try {
3318                         mInstaller.freeCache(volumeUuid, freeStorageSize);
3319                     } catch (InstallerException e) {
3320                         Slog.w(TAG, "Couldn't clear application caches: " + e);
3321                         success = false;
3322                     }
3323                 }
3324                 if (observer != null) {
3325                     try {
3326                         observer.onRemoveCompleted(null, success);
3327                     } catch (RemoteException e) {
3328                         Slog.w(TAG, "RemoveException when invoking call back");
3329                     }
3330                 }
3331             }
3332         });
3333     }
3334 
3335     @Override
3336     public void freeStorage(final String volumeUuid, final long freeStorageSize,
3337             final IntentSender pi) {
3338         mContext.enforceCallingOrSelfPermission(
3339                 android.Manifest.permission.CLEAR_APP_CACHE, null);
3340         // Queue up an async operation since clearing cache may take a little while.
3341         mHandler.post(new Runnable() {
3342             public void run() {
3343                 mHandler.removeCallbacks(this);
3344                 boolean success = true;
3345                 synchronized (mInstallLock) {
3346                     try {
3347                         mInstaller.freeCache(volumeUuid, freeStorageSize);
3348                     } catch (InstallerException e) {
3349                         Slog.w(TAG, "Couldn't clear application caches: " + e);
3350                         success = false;
3351                     }
3352                 }
3353                 if(pi != null) {
3354                     try {
3355                         // Callback via pending intent
3356                         int code = success ? 1 : 0;
3357                         pi.sendIntent(null, code, null,
3358                                 null, null);
3359                     } catch (SendIntentException e1) {
3360                         Slog.i(TAG, "Failed to send pending intent");
3361                     }
3362                 }
3363             }
3364         });
3365     }
3366 
3367     void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3368         synchronized (mInstallLock) {
3369             try {
3370                 mInstaller.freeCache(volumeUuid, freeStorageSize);
3371             } catch (InstallerException e) {
3372                 throw new IOException("Failed to free enough space", e);
3373             }
3374         }
3375     }
3376 
3377     /**
3378      * Update given flags based on encryption status of current user.
3379      */
3380     private int updateFlags(int flags, int userId) {
3381         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3382                 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3383             // Caller expressed an explicit opinion about what encryption
3384             // aware/unaware components they want to see, so fall through and
3385             // give them what they want
3386         } else {
3387             // Caller expressed no opinion, so match based on user state
3388             if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3389                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3390             } else {
3391                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3392             }
3393         }
3394         return flags;
3395     }
3396 
3397     private UserManagerInternal getUserManagerInternal() {
3398         if (mUserManagerInternal == null) {
3399             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3400         }
3401         return mUserManagerInternal;
3402     }
3403 
3404     /**
3405      * Update given flags when being used to request {@link PackageInfo}.
3406      */
3407     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3408         boolean triaged = true;
3409         if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3410                 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3411             // Caller is asking for component details, so they'd better be
3412             // asking for specific encryption matching behavior, or be triaged
3413             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3414                     | PackageManager.MATCH_DIRECT_BOOT_AWARE
3415                     | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3416                 triaged = false;
3417             }
3418         }
3419         if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3420                 | PackageManager.MATCH_SYSTEM_ONLY
3421                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3422             triaged = false;
3423         }
3424         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3425             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3426                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3427         }
3428         return updateFlags(flags, userId);
3429     }
3430 
3431     /**
3432      * Update given flags when being used to request {@link ApplicationInfo}.
3433      */
3434     private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3435         return updateFlagsForPackage(flags, userId, cookie);
3436     }
3437 
3438     /**
3439      * Update given flags when being used to request {@link ComponentInfo}.
3440      */
3441     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3442         if (cookie instanceof Intent) {
3443             if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3444                 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3445             }
3446         }
3447 
3448         boolean triaged = true;
3449         // Caller is asking for component details, so they'd better be
3450         // asking for specific encryption matching behavior, or be triaged
3451         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3452                 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3453                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3454             triaged = false;
3455         }
3456         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3457             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3458                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3459         }
3460 
3461         return updateFlags(flags, userId);
3462     }
3463 
3464     /**
3465      * Update given flags when being used to request {@link ResolveInfo}.
3466      */
3467     int updateFlagsForResolve(int flags, int userId, Object cookie) {
3468         // Safe mode means we shouldn't match any third-party components
3469         if (mSafeMode) {
3470             flags |= PackageManager.MATCH_SYSTEM_ONLY;
3471         }
3472 
3473         return updateFlagsForComponent(flags, userId, cookie);
3474     }
3475 
3476     @Override
3477     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3478         if (!sUserManager.exists(userId)) return null;
3479         flags = updateFlagsForComponent(flags, userId, component);
3480         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3481                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
3482         synchronized (mPackages) {
3483             PackageParser.Activity a = mActivities.mActivities.get(component);
3484 
3485             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3486             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3487                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3488                 if (ps == null) return null;
3489                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3490                         userId);
3491             }
3492             if (mResolveComponentName.equals(component)) {
3493                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
3494                         new PackageUserState(), userId);
3495             }
3496         }
3497         return null;
3498     }
3499 
3500     @Override
3501     public boolean activitySupportsIntent(ComponentName component, Intent intent,
3502             String resolvedType) {
3503         synchronized (mPackages) {
3504             if (component.equals(mResolveComponentName)) {
3505                 // The resolver supports EVERYTHING!
3506                 return true;
3507             }
3508             PackageParser.Activity a = mActivities.mActivities.get(component);
3509             if (a == null) {
3510                 return false;
3511             }
3512             for (int i=0; i<a.intents.size(); i++) {
3513                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3514                         intent.getData(), intent.getCategories(), TAG) >= 0) {
3515                     return true;
3516                 }
3517             }
3518             return false;
3519         }
3520     }
3521 
3522     @Override
3523     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3524         if (!sUserManager.exists(userId)) return null;
3525         flags = updateFlagsForComponent(flags, userId, component);
3526         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3527                 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
3528         synchronized (mPackages) {
3529             PackageParser.Activity a = mReceivers.mActivities.get(component);
3530             if (DEBUG_PACKAGE_INFO) Log.v(
3531                 TAG, "getReceiverInfo " + component + ": " + a);
3532             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3533                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3534                 if (ps == null) return null;
3535                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3536                         userId);
3537             }
3538         }
3539         return null;
3540     }
3541 
3542     @Override
3543     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3544         if (!sUserManager.exists(userId)) return null;
3545         flags = updateFlagsForComponent(flags, userId, component);
3546         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3547                 false /* requireFullPermission */, false /* checkShell */, "get service info");
3548         synchronized (mPackages) {
3549             PackageParser.Service s = mServices.mServices.get(component);
3550             if (DEBUG_PACKAGE_INFO) Log.v(
3551                 TAG, "getServiceInfo " + component + ": " + s);
3552             if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3553                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3554                 if (ps == null) return null;
3555                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3556                         userId);
3557             }
3558         }
3559         return null;
3560     }
3561 
3562     @Override
3563     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3564         if (!sUserManager.exists(userId)) return null;
3565         flags = updateFlagsForComponent(flags, userId, component);
3566         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3567                 false /* requireFullPermission */, false /* checkShell */, "get provider info");
3568         synchronized (mPackages) {
3569             PackageParser.Provider p = mProviders.mProviders.get(component);
3570             if (DEBUG_PACKAGE_INFO) Log.v(
3571                 TAG, "getProviderInfo " + component + ": " + p);
3572             if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3573                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3574                 if (ps == null) return null;
3575                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3576                         userId);
3577             }
3578         }
3579         return null;
3580     }
3581 
3582     @Override
3583     public String[] getSystemSharedLibraryNames() {
3584         Set<String> libSet;
3585         synchronized (mPackages) {
3586             libSet = mSharedLibraries.keySet();
3587             int size = libSet.size();
3588             if (size > 0) {
3589                 String[] libs = new String[size];
3590                 libSet.toArray(libs);
3591                 return libs;
3592             }
3593         }
3594         return null;
3595     }
3596 
3597     @Override
3598     public @NonNull String getServicesSystemSharedLibraryPackageName() {
3599         synchronized (mPackages) {
3600             return mServicesSystemSharedLibraryPackageName;
3601         }
3602     }
3603 
3604     @Override
3605     public @NonNull String getSharedSystemSharedLibraryPackageName() {
3606         synchronized (mPackages) {
3607             return mSharedSystemSharedLibraryPackageName;
3608         }
3609     }
3610 
3611     @Override
3612     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
3613         synchronized (mPackages) {
3614             final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
3615 
3616             final FeatureInfo fi = new FeatureInfo();
3617             fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3618                     FeatureInfo.GL_ES_VERSION_UNDEFINED);
3619             res.add(fi);
3620 
3621             return new ParceledListSlice<>(res);
3622         }
3623     }
3624 
3625     @Override
3626     public boolean hasSystemFeature(String name, int version) {
3627         synchronized (mPackages) {
3628             final FeatureInfo feat = mAvailableFeatures.get(name);
3629             if (feat == null) {
3630                 return false;
3631             } else {
3632                 return feat.version >= version;
3633             }
3634         }
3635     }
3636 
3637     @Override
3638     public int checkPermission(String permName, String pkgName, int userId) {
3639         if (!sUserManager.exists(userId)) {
3640             return PackageManager.PERMISSION_DENIED;
3641         }
3642 
3643         synchronized (mPackages) {
3644             final PackageParser.Package p = mPackages.get(pkgName);
3645             if (p != null && p.mExtras != null) {
3646                 final PackageSetting ps = (PackageSetting) p.mExtras;
3647                 final PermissionsState permissionsState = ps.getPermissionsState();
3648                 if (permissionsState.hasPermission(permName, userId)) {
3649                     return PackageManager.PERMISSION_GRANTED;
3650                 }
3651                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3652                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3653                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3654                     return PackageManager.PERMISSION_GRANTED;
3655                 }
3656             }
3657         }
3658 
3659         return PackageManager.PERMISSION_DENIED;
3660     }
3661 
3662     @Override
3663     public int checkUidPermission(String permName, int uid) {
3664         final int userId = UserHandle.getUserId(uid);
3665 
3666         if (!sUserManager.exists(userId)) {
3667             return PackageManager.PERMISSION_DENIED;
3668         }
3669 
3670         synchronized (mPackages) {
3671             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3672             if (obj != null) {
3673                 final SettingBase ps = (SettingBase) obj;
3674                 final PermissionsState permissionsState = ps.getPermissionsState();
3675                 if (permissionsState.hasPermission(permName, userId)) {
3676                     return PackageManager.PERMISSION_GRANTED;
3677                 }
3678                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3679                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3680                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3681                     return PackageManager.PERMISSION_GRANTED;
3682                 }
3683             } else {
3684                 ArraySet<String> perms = mSystemPermissions.get(uid);
3685                 if (perms != null) {
3686                     if (perms.contains(permName)) {
3687                         return PackageManager.PERMISSION_GRANTED;
3688                     }
3689                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3690                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3691                         return PackageManager.PERMISSION_GRANTED;
3692                     }
3693                 }
3694             }
3695         }
3696 
3697         return PackageManager.PERMISSION_DENIED;
3698     }
3699 
3700     @Override
3701     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3702         if (UserHandle.getCallingUserId() != userId) {
3703             mContext.enforceCallingPermission(
3704                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3705                     "isPermissionRevokedByPolicy for user " + userId);
3706         }
3707 
3708         if (checkPermission(permission, packageName, userId)
3709                 == PackageManager.PERMISSION_GRANTED) {
3710             return false;
3711         }
3712 
3713         final long identity = Binder.clearCallingIdentity();
3714         try {
3715             final int flags = getPermissionFlags(permission, packageName, userId);
3716             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3717         } finally {
3718             Binder.restoreCallingIdentity(identity);
3719         }
3720     }
3721 
3722     @Override
3723     public String getPermissionControllerPackageName() {
3724         synchronized (mPackages) {
3725             return mRequiredInstallerPackage;
3726         }
3727     }
3728 
3729     /**
3730      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3731      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3732      * @param checkShell whether to prevent shell from access if there's a debugging restriction
3733      * @param message the message to log on security exception
3734      */
3735     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3736             boolean checkShell, String message) {
3737         if (userId < 0) {
3738             throw new IllegalArgumentException("Invalid userId " + userId);
3739         }
3740         if (checkShell) {
3741             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3742         }
3743         if (userId == UserHandle.getUserId(callingUid)) return;
3744         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3745             if (requireFullPermission) {
3746                 mContext.enforceCallingOrSelfPermission(
3747                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3748             } else {
3749                 try {
3750                     mContext.enforceCallingOrSelfPermission(
3751                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3752                 } catch (SecurityException se) {
3753                     mContext.enforceCallingOrSelfPermission(
3754                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3755                 }
3756             }
3757         }
3758     }
3759 
3760     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3761         if (callingUid == Process.SHELL_UID) {
3762             if (userHandle >= 0
3763                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
3764                 throw new SecurityException("Shell does not have permission to access user "
3765                         + userHandle);
3766             } else if (userHandle < 0) {
3767                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3768                         + Debug.getCallers(3));
3769             }
3770         }
3771     }
3772 
3773     private BasePermission findPermissionTreeLP(String permName) {
3774         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3775             if (permName.startsWith(bp.name) &&
3776                     permName.length() > bp.name.length() &&
3777                     permName.charAt(bp.name.length()) == '.') {
3778                 return bp;
3779             }
3780         }
3781         return null;
3782     }
3783 
3784     private BasePermission checkPermissionTreeLP(String permName) {
3785         if (permName != null) {
3786             BasePermission bp = findPermissionTreeLP(permName);
3787             if (bp != null) {
3788                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3789                     return bp;
3790                 }
3791                 throw new SecurityException("Calling uid "
3792                         + Binder.getCallingUid()
3793                         + " is not allowed to add to permission tree "
3794                         + bp.name + " owned by uid " + bp.uid);
3795             }
3796         }
3797         throw new SecurityException("No permission tree found for " + permName);
3798     }
3799 
3800     static boolean compareStrings(CharSequence s1, CharSequence s2) {
3801         if (s1 == null) {
3802             return s2 == null;
3803         }
3804         if (s2 == null) {
3805             return false;
3806         }
3807         if (s1.getClass() != s2.getClass()) {
3808             return false;
3809         }
3810         return s1.equals(s2);
3811     }
3812 
3813     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3814         if (pi1.icon != pi2.icon) return false;
3815         if (pi1.logo != pi2.logo) return false;
3816         if (pi1.protectionLevel != pi2.protectionLevel) return false;
3817         if (!compareStrings(pi1.name, pi2.name)) return false;
3818         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3819         // We'll take care of setting this one.
3820         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3821         // These are not currently stored in settings.
3822         //if (!compareStrings(pi1.group, pi2.group)) return false;
3823         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3824         //if (pi1.labelRes != pi2.labelRes) return false;
3825         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3826         return true;
3827     }
3828 
3829     int permissionInfoFootprint(PermissionInfo info) {
3830         int size = info.name.length();
3831         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3832         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3833         return size;
3834     }
3835 
3836     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3837         int size = 0;
3838         for (BasePermission perm : mSettings.mPermissions.values()) {
3839             if (perm.uid == tree.uid) {
3840                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3841             }
3842         }
3843         return size;
3844     }
3845 
3846     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3847         // We calculate the max size of permissions defined by this uid and throw
3848         // if that plus the size of 'info' would exceed our stated maximum.
3849         if (tree.uid != Process.SYSTEM_UID) {
3850             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3851             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3852                 throw new SecurityException("Permission tree size cap exceeded");
3853             }
3854         }
3855     }
3856 
3857     boolean addPermissionLocked(PermissionInfo info, boolean async) {
3858         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3859             throw new SecurityException("Label must be specified in permission");
3860         }
3861         BasePermission tree = checkPermissionTreeLP(info.name);
3862         BasePermission bp = mSettings.mPermissions.get(info.name);
3863         boolean added = bp == null;
3864         boolean changed = true;
3865         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3866         if (added) {
3867             enforcePermissionCapLocked(info, tree);
3868             bp = new BasePermission(info.name, tree.sourcePackage,
3869                     BasePermission.TYPE_DYNAMIC);
3870         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3871             throw new SecurityException(
3872                     "Not allowed to modify non-dynamic permission "
3873                     + info.name);
3874         } else {
3875             if (bp.protectionLevel == fixedLevel
3876                     && bp.perm.owner.equals(tree.perm.owner)
3877                     && bp.uid == tree.uid
3878                     && comparePermissionInfos(bp.perm.info, info)) {
3879                 changed = false;
3880             }
3881         }
3882         bp.protectionLevel = fixedLevel;
3883         info = new PermissionInfo(info);
3884         info.protectionLevel = fixedLevel;
3885         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3886         bp.perm.info.packageName = tree.perm.info.packageName;
3887         bp.uid = tree.uid;
3888         if (added) {
3889             mSettings.mPermissions.put(info.name, bp);
3890         }
3891         if (changed) {
3892             if (!async) {
3893                 mSettings.writeLPr();
3894             } else {
3895                 scheduleWriteSettingsLocked();
3896             }
3897         }
3898         return added;
3899     }
3900 
3901     @Override
3902     public boolean addPermission(PermissionInfo info) {
3903         synchronized (mPackages) {
3904             return addPermissionLocked(info, false);
3905         }
3906     }
3907 
3908     @Override
3909     public boolean addPermissionAsync(PermissionInfo info) {
3910         synchronized (mPackages) {
3911             return addPermissionLocked(info, true);
3912         }
3913     }
3914 
3915     @Override
3916     public void removePermission(String name) {
3917         synchronized (mPackages) {
3918             checkPermissionTreeLP(name);
3919             BasePermission bp = mSettings.mPermissions.get(name);
3920             if (bp != null) {
3921                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
3922                     throw new SecurityException(
3923                             "Not allowed to modify non-dynamic permission "
3924                             + name);
3925                 }
3926                 mSettings.mPermissions.remove(name);
3927                 mSettings.writeLPr();
3928             }
3929         }
3930     }
3931 
3932     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
3933             BasePermission bp) {
3934         int index = pkg.requestedPermissions.indexOf(bp.name);
3935         if (index == -1) {
3936             throw new SecurityException("Package " + pkg.packageName
3937                     + " has not requested permission " + bp.name);
3938         }
3939         if (!bp.isRuntime() && !bp.isDevelopment()) {
3940             throw new SecurityException("Permission " + bp.name
3941                     + " is not a changeable permission type");
3942         }
3943     }
3944 
3945     @Override
3946     public void grantRuntimePermission(String packageName, String name, final int userId) {
3947         if (!sUserManager.exists(userId)) {
3948             Log.e(TAG, "No such user:" + userId);
3949             return;
3950         }
3951 
3952         mContext.enforceCallingOrSelfPermission(
3953                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
3954                 "grantRuntimePermission");
3955 
3956         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3957                 true /* requireFullPermission */, true /* checkShell */,
3958                 "grantRuntimePermission");
3959 
3960         final int uid;
3961         final SettingBase sb;
3962 
3963         synchronized (mPackages) {
3964             final PackageParser.Package pkg = mPackages.get(packageName);
3965             if (pkg == null) {
3966                 throw new IllegalArgumentException("Unknown package: " + packageName);
3967             }
3968 
3969             final BasePermission bp = mSettings.mPermissions.get(name);
3970             if (bp == null) {
3971                 throw new IllegalArgumentException("Unknown permission: " + name);
3972             }
3973 
3974             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3975 
3976             // If a permission review is required for legacy apps we represent
3977             // their permissions as always granted runtime ones since we need
3978             // to keep the review required permission flag per user while an
3979             // install permission's state is shared across all users.
3980             if (Build.PERMISSIONS_REVIEW_REQUIRED
3981                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3982                     && bp.isRuntime()) {
3983                 return;
3984             }
3985 
3986             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
3987             sb = (SettingBase) pkg.mExtras;
3988             if (sb == null) {
3989                 throw new IllegalArgumentException("Unknown package: " + packageName);
3990             }
3991 
3992             final PermissionsState permissionsState = sb.getPermissionsState();
3993 
3994             final int flags = permissionsState.getPermissionFlags(name, userId);
3995             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3996                 throw new SecurityException("Cannot grant system fixed permission "
3997                         + name + " for package " + packageName);
3998             }
3999 
4000             if (bp.isDevelopment()) {
4001                 // Development permissions must be handled specially, since they are not
4002                 // normal runtime permissions.  For now they apply to all users.
4003                 if (permissionsState.grantInstallPermission(bp) !=
4004                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4005                     scheduleWriteSettingsLocked();
4006                 }
4007                 return;
4008             }
4009 
4010             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4011                 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4012                 return;
4013             }
4014 
4015             final int result = permissionsState.grantRuntimePermission(bp, userId);
4016             switch (result) {
4017                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4018                     return;
4019                 }
4020 
4021                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4022                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4023                     mHandler.post(new Runnable() {
4024                         @Override
4025                         public void run() {
4026                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4027                         }
4028                     });
4029                 }
4030                 break;
4031             }
4032 
4033             mOnPermissionChangeListeners.onPermissionsChanged(uid);
4034 
4035             // Not critical if that is lost - app has to request again.
4036             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4037         }
4038 
4039         // Only need to do this if user is initialized. Otherwise it's a new user
4040         // and there are no processes running as the user yet and there's no need
4041         // to make an expensive call to remount processes for the changed permissions.
4042         if (READ_EXTERNAL_STORAGE.equals(name)
4043                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
4044             final long token = Binder.clearCallingIdentity();
4045             try {
4046                 if (sUserManager.isInitialized(userId)) {
4047                     MountServiceInternal mountServiceInternal = LocalServices.getService(
4048                             MountServiceInternal.class);
4049                     mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
4050                 }
4051             } finally {
4052                 Binder.restoreCallingIdentity(token);
4053             }
4054         }
4055     }
4056 
4057     @Override
4058     public void revokeRuntimePermission(String packageName, String name, int userId) {
4059         if (!sUserManager.exists(userId)) {
4060             Log.e(TAG, "No such user:" + userId);
4061             return;
4062         }
4063 
4064         mContext.enforceCallingOrSelfPermission(
4065                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4066                 "revokeRuntimePermission");
4067 
4068         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4069                 true /* requireFullPermission */, true /* checkShell */,
4070                 "revokeRuntimePermission");
4071 
4072         final int appId;
4073 
4074         synchronized (mPackages) {
4075             final PackageParser.Package pkg = mPackages.get(packageName);
4076             if (pkg == null) {
4077                 throw new IllegalArgumentException("Unknown package: " + packageName);
4078             }
4079 
4080             final BasePermission bp = mSettings.mPermissions.get(name);
4081             if (bp == null) {
4082                 throw new IllegalArgumentException("Unknown permission: " + name);
4083             }
4084 
4085             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4086 
4087             // If a permission review is required for legacy apps we represent
4088             // their permissions as always granted runtime ones since we need
4089             // to keep the review required permission flag per user while an
4090             // install permission's state is shared across all users.
4091             if (Build.PERMISSIONS_REVIEW_REQUIRED
4092                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4093                     && bp.isRuntime()) {
4094                 return;
4095             }
4096 
4097             SettingBase sb = (SettingBase) pkg.mExtras;
4098             if (sb == null) {
4099                 throw new IllegalArgumentException("Unknown package: " + packageName);
4100             }
4101 
4102             final PermissionsState permissionsState = sb.getPermissionsState();
4103 
4104             final int flags = permissionsState.getPermissionFlags(name, userId);
4105             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4106                 throw new SecurityException("Cannot revoke system fixed permission "
4107                         + name + " for package " + packageName);
4108             }
4109 
4110             if (bp.isDevelopment()) {
4111                 // Development permissions must be handled specially, since they are not
4112                 // normal runtime permissions.  For now they apply to all users.
4113                 if (permissionsState.revokeInstallPermission(bp) !=
4114                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4115                     scheduleWriteSettingsLocked();
4116                 }
4117                 return;
4118             }
4119 
4120             if (permissionsState.revokeRuntimePermission(bp, userId) ==
4121                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
4122                 return;
4123             }
4124 
4125             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4126 
4127             // Critical, after this call app should never have the permission.
4128             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4129 
4130             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4131         }
4132 
4133         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4134     }
4135 
4136     @Override
4137     public void resetRuntimePermissions() {
4138         mContext.enforceCallingOrSelfPermission(
4139                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4140                 "revokeRuntimePermission");
4141 
4142         int callingUid = Binder.getCallingUid();
4143         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4144             mContext.enforceCallingOrSelfPermission(
4145                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4146                     "resetRuntimePermissions");
4147         }
4148 
4149         synchronized (mPackages) {
4150             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
4151             for (int userId : UserManagerService.getInstance().getUserIds()) {
4152                 final int packageCount = mPackages.size();
4153                 for (int i = 0; i < packageCount; i++) {
4154                     PackageParser.Package pkg = mPackages.valueAt(i);
4155                     if (!(pkg.mExtras instanceof PackageSetting)) {
4156                         continue;
4157                     }
4158                     PackageSetting ps = (PackageSetting) pkg.mExtras;
4159                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
4160                 }
4161             }
4162         }
4163     }
4164 
4165     @Override
4166     public int getPermissionFlags(String name, String packageName, int userId) {
4167         if (!sUserManager.exists(userId)) {
4168             return 0;
4169         }
4170 
4171         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
4172 
4173         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4174                 true /* requireFullPermission */, false /* checkShell */,
4175                 "getPermissionFlags");
4176 
4177         synchronized (mPackages) {
4178             final PackageParser.Package pkg = mPackages.get(packageName);
4179             if (pkg == null) {
4180                 return 0;
4181             }
4182 
4183             final BasePermission bp = mSettings.mPermissions.get(name);
4184             if (bp == null) {
4185                 return 0;
4186             }
4187 
4188             SettingBase sb = (SettingBase) pkg.mExtras;
4189             if (sb == null) {
4190                 return 0;
4191             }
4192 
4193             PermissionsState permissionsState = sb.getPermissionsState();
4194             return permissionsState.getPermissionFlags(name, userId);
4195         }
4196     }
4197 
4198     @Override
4199     public void updatePermissionFlags(String name, String packageName, int flagMask,
4200             int flagValues, int userId) {
4201         if (!sUserManager.exists(userId)) {
4202             return;
4203         }
4204 
4205         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
4206 
4207         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4208                 true /* requireFullPermission */, true /* checkShell */,
4209                 "updatePermissionFlags");
4210 
4211         // Only the system can change these flags and nothing else.
4212         if (getCallingUid() != Process.SYSTEM_UID) {
4213             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4214             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4215             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4216             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4217             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
4218         }
4219 
4220         synchronized (mPackages) {
4221             final PackageParser.Package pkg = mPackages.get(packageName);
4222             if (pkg == null) {
4223                 throw new IllegalArgumentException("Unknown package: " + packageName);
4224             }
4225 
4226             final BasePermission bp = mSettings.mPermissions.get(name);
4227             if (bp == null) {
4228                 throw new IllegalArgumentException("Unknown permission: " + name);
4229             }
4230 
4231             SettingBase sb = (SettingBase) pkg.mExtras;
4232             if (sb == null) {
4233                 throw new IllegalArgumentException("Unknown package: " + packageName);
4234             }
4235 
4236             PermissionsState permissionsState = sb.getPermissionsState();
4237 
4238             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
4239 
4240             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
4241                 // Install and runtime permissions are stored in different places,
4242                 // so figure out what permission changed and persist the change.
4243                 if (permissionsState.getInstallPermissionState(name) != null) {
4244                     scheduleWriteSettingsLocked();
4245                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
4246                         || hadState) {
4247                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4248                 }
4249             }
4250         }
4251     }
4252 
4253     /**
4254      * Update the permission flags for all packages and runtime permissions of a user in order
4255      * to allow device or profile owner to remove POLICY_FIXED.
4256      */
4257     @Override
4258     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
4259         if (!sUserManager.exists(userId)) {
4260             return;
4261         }
4262 
4263         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
4264 
4265         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4266                 true /* requireFullPermission */, true /* checkShell */,
4267                 "updatePermissionFlagsForAllApps");
4268 
4269         // Only the system can change system fixed flags.
4270         if (getCallingUid() != Process.SYSTEM_UID) {
4271             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4272             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4273         }
4274 
4275         synchronized (mPackages) {
4276             boolean changed = false;
4277             final int packageCount = mPackages.size();
4278             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4279                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4280                 SettingBase sb = (SettingBase) pkg.mExtras;
4281                 if (sb == null) {
4282                     continue;
4283                 }
4284                 PermissionsState permissionsState = sb.getPermissionsState();
4285                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4286                         userId, flagMask, flagValues);
4287             }
4288             if (changed) {
4289                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4290             }
4291         }
4292     }
4293 
4294     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4295         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4296                 != PackageManager.PERMISSION_GRANTED
4297             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4298                 != PackageManager.PERMISSION_GRANTED) {
4299             throw new SecurityException(message + " requires "
4300                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4301                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4302         }
4303     }
4304 
4305     @Override
4306     public boolean shouldShowRequestPermissionRationale(String permissionName,
4307             String packageName, int userId) {
4308         if (UserHandle.getCallingUserId() != userId) {
4309             mContext.enforceCallingPermission(
4310                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4311                     "canShowRequestPermissionRationale for user " + userId);
4312         }
4313 
4314         final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
4315         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4316             return false;
4317         }
4318 
4319         if (checkPermission(permissionName, packageName, userId)
4320                 == PackageManager.PERMISSION_GRANTED) {
4321             return false;
4322         }
4323 
4324         final int flags;
4325 
4326         final long identity = Binder.clearCallingIdentity();
4327         try {
4328             flags = getPermissionFlags(permissionName,
4329                     packageName, userId);
4330         } finally {
4331             Binder.restoreCallingIdentity(identity);
4332         }
4333 
4334         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4335                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4336                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
4337 
4338         if ((flags & fixedFlags) != 0) {
4339             return false;
4340         }
4341 
4342         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4343     }
4344 
4345     @Override
4346     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4347         mContext.enforceCallingOrSelfPermission(
4348                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4349                 "addOnPermissionsChangeListener");
4350 
4351         synchronized (mPackages) {
4352             mOnPermissionChangeListeners.addListenerLocked(listener);
4353         }
4354     }
4355 
4356     @Override
4357     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4358         synchronized (mPackages) {
4359             mOnPermissionChangeListeners.removeListenerLocked(listener);
4360         }
4361     }
4362 
4363     @Override
4364     public boolean isProtectedBroadcast(String actionName) {
4365         synchronized (mPackages) {
4366             if (mProtectedBroadcasts.contains(actionName)) {
4367                 return true;
4368             } else if (actionName != null) {
4369                 // TODO: remove these terrible hacks
4370                 if (actionName.startsWith("android.net.netmon.lingerExpired")
4371                         || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
4372                         || actionName.startsWith("com.android.internal.telephony.data-reconnect")
4373                         || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
4374                     return true;
4375                 }
4376             }
4377         }
4378         return false;
4379     }
4380 
4381     @Override
4382     public int checkSignatures(String pkg1, String pkg2) {
4383         synchronized (mPackages) {
4384             final PackageParser.Package p1 = mPackages.get(pkg1);
4385             final PackageParser.Package p2 = mPackages.get(pkg2);
4386             if (p1 == null || p1.mExtras == null
4387                     || p2 == null || p2.mExtras == null) {
4388                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4389             }
4390             return compareSignatures(p1.mSignatures, p2.mSignatures);
4391         }
4392     }
4393 
4394     @Override
4395     public int checkUidSignatures(int uid1, int uid2) {
4396         // Map to base uids.
4397         uid1 = UserHandle.getAppId(uid1);
4398         uid2 = UserHandle.getAppId(uid2);
4399         // reader
4400         synchronized (mPackages) {
4401             Signature[] s1;
4402             Signature[] s2;
4403             Object obj = mSettings.getUserIdLPr(uid1);
4404             if (obj != null) {
4405                 if (obj instanceof SharedUserSetting) {
4406                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4407                 } else if (obj instanceof PackageSetting) {
4408                     s1 = ((PackageSetting)obj).signatures.mSignatures;
4409                 } else {
4410                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4411                 }
4412             } else {
4413                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4414             }
4415             obj = mSettings.getUserIdLPr(uid2);
4416             if (obj != null) {
4417                 if (obj instanceof SharedUserSetting) {
4418                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4419                 } else if (obj instanceof PackageSetting) {
4420                     s2 = ((PackageSetting)obj).signatures.mSignatures;
4421                 } else {
4422                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4423                 }
4424             } else {
4425                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4426             }
4427             return compareSignatures(s1, s2);
4428         }
4429     }
4430 
4431     /**
4432      * This method should typically only be used when granting or revoking
4433      * permissions, since the app may immediately restart after this call.
4434      * <p>
4435      * If you're doing surgery on app code/data, use {@link PackageFreezer} to
4436      * guard your work against the app being relaunched.
4437      */
4438     private void killUid(int appId, int userId, String reason) {
4439         final long identity = Binder.clearCallingIdentity();
4440         try {
4441             IActivityManager am = ActivityManagerNative.getDefault();
4442             if (am != null) {
4443                 try {
4444                     am.killUid(appId, userId, reason);
4445                 } catch (RemoteException e) {
4446                     /* ignore - same process */
4447                 }
4448             }
4449         } finally {
4450             Binder.restoreCallingIdentity(identity);
4451         }
4452     }
4453 
4454     /**
4455      * Compares two sets of signatures. Returns:
4456      * <br />
4457      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4458      * <br />
4459      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4460      * <br />
4461      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4462      * <br />
4463      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4464      * <br />
4465      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4466      */
4467     static int compareSignatures(Signature[] s1, Signature[] s2) {
4468         if (s1 == null) {
4469             return s2 == null
4470                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
4471                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4472         }
4473 
4474         if (s2 == null) {
4475             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4476         }
4477 
4478         if (s1.length != s2.length) {
4479             return PackageManager.SIGNATURE_NO_MATCH;
4480         }
4481 
4482         // Since both signature sets are of size 1, we can compare without HashSets.
4483         if (s1.length == 1) {
4484             return s1[0].equals(s2[0]) ?
4485                     PackageManager.SIGNATURE_MATCH :
4486                     PackageManager.SIGNATURE_NO_MATCH;
4487         }
4488 
4489         ArraySet<Signature> set1 = new ArraySet<Signature>();
4490         for (Signature sig : s1) {
4491             set1.add(sig);
4492         }
4493         ArraySet<Signature> set2 = new ArraySet<Signature>();
4494         for (Signature sig : s2) {
4495             set2.add(sig);
4496         }
4497         // Make sure s2 contains all signatures in s1.
4498         if (set1.equals(set2)) {
4499             return PackageManager.SIGNATURE_MATCH;
4500         }
4501         return PackageManager.SIGNATURE_NO_MATCH;
4502     }
4503 
4504     /**
4505      * If the database version for this type of package (internal storage or
4506      * external storage) is less than the version where package signatures
4507      * were updated, return true.
4508      */
4509     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4510         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4511         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4512     }
4513 
4514     /**
4515      * Used for backward compatibility to make sure any packages with
4516      * certificate chains get upgraded to the new style. {@code existingSigs}
4517      * will be in the old format (since they were stored on disk from before the
4518      * system upgrade) and {@code scannedSigs} will be in the newer format.
4519      */
4520     private int compareSignaturesCompat(PackageSignatures existingSigs,
4521             PackageParser.Package scannedPkg) {
4522         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4523             return PackageManager.SIGNATURE_NO_MATCH;
4524         }
4525 
4526         ArraySet<Signature> existingSet = new ArraySet<Signature>();
4527         for (Signature sig : existingSigs.mSignatures) {
4528             existingSet.add(sig);
4529         }
4530         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4531         for (Signature sig : scannedPkg.mSignatures) {
4532             try {
4533                 Signature[] chainSignatures = sig.getChainSignatures();
4534                 for (Signature chainSig : chainSignatures) {
4535                     scannedCompatSet.add(chainSig);
4536                 }
4537             } catch (CertificateEncodingException e) {
4538                 scannedCompatSet.add(sig);
4539             }
4540         }
4541         /*
4542          * Make sure the expanded scanned set contains all signatures in the
4543          * existing one.
4544          */
4545         if (scannedCompatSet.equals(existingSet)) {
4546             // Migrate the old signatures to the new scheme.
4547             existingSigs.assignSignatures(scannedPkg.mSignatures);
4548             // The new KeySets will be re-added later in the scanning process.
4549             synchronized (mPackages) {
4550                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4551             }
4552             return PackageManager.SIGNATURE_MATCH;
4553         }
4554         return PackageManager.SIGNATURE_NO_MATCH;
4555     }
4556 
4557     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4558         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4559         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4560     }
4561 
4562     private int compareSignaturesRecover(PackageSignatures existingSigs,
4563             PackageParser.Package scannedPkg) {
4564         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4565             return PackageManager.SIGNATURE_NO_MATCH;
4566         }
4567 
4568         String msg = null;
4569         try {
4570             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4571                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4572                         + scannedPkg.packageName);
4573                 return PackageManager.SIGNATURE_MATCH;
4574             }
4575         } catch (CertificateException e) {
4576             msg = e.getMessage();
4577         }
4578 
4579         logCriticalInfo(Log.INFO,
4580                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4581         return PackageManager.SIGNATURE_NO_MATCH;
4582     }
4583 
4584     @Override
4585     public List<String> getAllPackages() {
4586         synchronized (mPackages) {
4587             return new ArrayList<String>(mPackages.keySet());
4588         }
4589     }
4590 
4591     @Override
4592     public String[] getPackagesForUid(int uid) {
4593         uid = UserHandle.getAppId(uid);
4594         // reader
4595         synchronized (mPackages) {
4596             Object obj = mSettings.getUserIdLPr(uid);
4597             if (obj instanceof SharedUserSetting) {
4598                 final SharedUserSetting sus = (SharedUserSetting) obj;
4599                 final int N = sus.packages.size();
4600                 final String[] res = new String[N];
4601                 for (int i = 0; i < N; i++) {
4602                     res[i] = sus.packages.valueAt(i).name;
4603                 }
4604                 return res;
4605             } else if (obj instanceof PackageSetting) {
4606                 final PackageSetting ps = (PackageSetting) obj;
4607                 return new String[] { ps.name };
4608             }
4609         }
4610         return null;
4611     }
4612 
4613     @Override
4614     public String getNameForUid(int uid) {
4615         // reader
4616         synchronized (mPackages) {
4617             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4618             if (obj instanceof SharedUserSetting) {
4619                 final SharedUserSetting sus = (SharedUserSetting) obj;
4620                 return sus.name + ":" + sus.userId;
4621             } else if (obj instanceof PackageSetting) {
4622                 final PackageSetting ps = (PackageSetting) obj;
4623                 return ps.name;
4624             }
4625         }
4626         return null;
4627     }
4628 
4629     @Override
4630     public int getUidForSharedUser(String sharedUserName) {
4631         if(sharedUserName == null) {
4632             return -1;
4633         }
4634         // reader
4635         synchronized (mPackages) {
4636             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4637             if (suid == null) {
4638                 return -1;
4639             }
4640             return suid.userId;
4641         }
4642     }
4643 
4644     @Override
4645     public int getFlagsForUid(int uid) {
4646         synchronized (mPackages) {
4647             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4648             if (obj instanceof SharedUserSetting) {
4649                 final SharedUserSetting sus = (SharedUserSetting) obj;
4650                 return sus.pkgFlags;
4651             } else if (obj instanceof PackageSetting) {
4652                 final PackageSetting ps = (PackageSetting) obj;
4653                 return ps.pkgFlags;
4654             }
4655         }
4656         return 0;
4657     }
4658 
4659     @Override
4660     public int getPrivateFlagsForUid(int uid) {
4661         synchronized (mPackages) {
4662             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4663             if (obj instanceof SharedUserSetting) {
4664                 final SharedUserSetting sus = (SharedUserSetting) obj;
4665                 return sus.pkgPrivateFlags;
4666             } else if (obj instanceof PackageSetting) {
4667                 final PackageSetting ps = (PackageSetting) obj;
4668                 return ps.pkgPrivateFlags;
4669             }
4670         }
4671         return 0;
4672     }
4673 
4674     @Override
4675     public boolean isUidPrivileged(int uid) {
4676         uid = UserHandle.getAppId(uid);
4677         // reader
4678         synchronized (mPackages) {
4679             Object obj = mSettings.getUserIdLPr(uid);
4680             if (obj instanceof SharedUserSetting) {
4681                 final SharedUserSetting sus = (SharedUserSetting) obj;
4682                 final Iterator<PackageSetting> it = sus.packages.iterator();
4683                 while (it.hasNext()) {
4684                     if (it.next().isPrivileged()) {
4685                         return true;
4686                     }
4687                 }
4688             } else if (obj instanceof PackageSetting) {
4689                 final PackageSetting ps = (PackageSetting) obj;
4690                 return ps.isPrivileged();
4691             }
4692         }
4693         return false;
4694     }
4695 
4696     @Override
4697     public String[] getAppOpPermissionPackages(String permissionName) {
4698         synchronized (mPackages) {
4699             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4700             if (pkgs == null) {
4701                 return null;
4702             }
4703             return pkgs.toArray(new String[pkgs.size()]);
4704         }
4705     }
4706 
4707     @Override
4708     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4709             int flags, int userId) {
4710         try {
4711             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
4712 
4713             if (!sUserManager.exists(userId)) return null;
4714             flags = updateFlagsForResolve(flags, userId, intent);
4715             enforceCrossUserPermission(Binder.getCallingUid(), userId,
4716                     false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
4717 
4718             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
4719             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
4720                     flags, userId);
4721             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4722 
4723             final ResolveInfo bestChoice =
4724                     chooseBestActivity(intent, resolvedType, flags, query, userId);
4725 
4726             if (isEphemeralAllowed(intent, query, userId)) {
4727                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
4728                 final EphemeralResolveInfo ai =
4729                         getEphemeralResolveInfo(intent, resolvedType, userId);
4730                 if (ai != null) {
4731                     if (DEBUG_EPHEMERAL) {
4732                         Slog.v(TAG, "Returning an EphemeralResolveInfo");
4733                     }
4734                     bestChoice.ephemeralInstaller = mEphemeralInstallerInfo;
4735                     bestChoice.ephemeralResolveInfo = ai;
4736                 }
4737                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4738             }
4739             return bestChoice;
4740         } finally {
4741             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4742         }
4743     }
4744 
4745     @Override
4746     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4747             IntentFilter filter, int match, ComponentName activity) {
4748         final int userId = UserHandle.getCallingUserId();
4749         if (DEBUG_PREFERRED) {
4750             Log.v(TAG, "setLastChosenActivity intent=" + intent
4751                 + " resolvedType=" + resolvedType
4752                 + " flags=" + flags
4753                 + " filter=" + filter
4754                 + " match=" + match
4755                 + " activity=" + activity);
4756             filter.dump(new PrintStreamPrinter(System.out), "    ");
4757         }
4758         intent.setComponent(null);
4759         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4760                 userId);
4761         // Find any earlier preferred or last chosen entries and nuke them
4762         findPreferredActivity(intent, resolvedType,
4763                 flags, query, 0, false, true, false, userId);
4764         // Add the new activity as the last chosen for this filter
4765         addPreferredActivityInternal(filter, match, null, activity, false, userId,
4766                 "Setting last chosen");
4767     }
4768 
4769     @Override
4770     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4771         final int userId = UserHandle.getCallingUserId();
4772         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4773         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4774                 userId);
4775         return findPreferredActivity(intent, resolvedType, flags, query, 0,
4776                 false, false, false, userId);
4777     }
4778 
4779 
4780     private boolean isEphemeralAllowed(
4781             Intent intent, List<ResolveInfo> resolvedActivites, int userId) {
4782         // Short circuit and return early if possible.
4783         if (DISABLE_EPHEMERAL_APPS) {
4784             return false;
4785         }
4786         final int callingUser = UserHandle.getCallingUserId();
4787         if (callingUser != UserHandle.USER_SYSTEM) {
4788             return false;
4789         }
4790         if (mEphemeralResolverConnection == null) {
4791             return false;
4792         }
4793         if (intent.getComponent() != null) {
4794             return false;
4795         }
4796         if (intent.getPackage() != null) {
4797             return false;
4798         }
4799         final boolean isWebUri = hasWebURI(intent);
4800         if (!isWebUri) {
4801             return false;
4802         }
4803         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4804         synchronized (mPackages) {
4805             final int count = resolvedActivites.size();
4806             for (int n = 0; n < count; n++) {
4807                 ResolveInfo info = resolvedActivites.get(n);
4808                 String packageName = info.activityInfo.packageName;
4809                 PackageSetting ps = mSettings.mPackages.get(packageName);
4810                 if (ps != null) {
4811                     // Try to get the status from User settings first
4812                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4813                     int status = (int) (packedStatus >> 32);
4814                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
4815                             || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4816                         if (DEBUG_EPHEMERAL) {
4817                             Slog.v(TAG, "DENY ephemeral apps;"
4818                                 + " pkg: " + packageName + ", status: " + status);
4819                         }
4820                         return false;
4821                     }
4822                 }
4823             }
4824         }
4825         // We've exhausted all ways to deny ephemeral application; let the system look for them.
4826         return true;
4827     }
4828 
4829     private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType,
4830             int userId) {
4831         final int ephemeralPrefixMask = Global.getInt(mContext.getContentResolver(),
4832                 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK);
4833         final int ephemeralPrefixCount = Global.getInt(mContext.getContentResolver(),
4834                 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT);
4835         final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask,
4836                 ephemeralPrefixCount);
4837         final int[] shaPrefix = digest.getDigestPrefix();
4838         final byte[][] digestBytes = digest.getDigestBytes();
4839         final List<EphemeralResolveInfo> ephemeralResolveInfoList =
4840                 mEphemeralResolverConnection.getEphemeralResolveInfoList(
4841                         shaPrefix, ephemeralPrefixMask);
4842         if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
4843             // No hash prefix match; there are no ephemeral apps for this domain.
4844             return null;
4845         }
4846 
4847         // Go in reverse order so we match the narrowest scope first.
4848         for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
4849             for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
4850                 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
4851                     continue;
4852                 }
4853                 final List<IntentFilter> filters = ephemeralApplication.getFilters();
4854                 // No filters; this should never happen.
4855                 if (filters.isEmpty()) {
4856                     continue;
4857                 }
4858                 // We have a domain match; resolve the filters to see if anything matches.
4859                 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
4860                 for (int j = filters.size() - 1; j >= 0; --j) {
4861                     final EphemeralResolveIntentInfo intentInfo =
4862                             new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
4863                     ephemeralResolver.addFilter(intentInfo);
4864                 }
4865                 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
4866                         intent, resolvedType, false /*defaultOnly*/, userId);
4867                 if (!matchedResolveInfoList.isEmpty()) {
4868                     return matchedResolveInfoList.get(0);
4869                 }
4870             }
4871         }
4872         // Hash or filter mis-match; no ephemeral apps for this domain.
4873         return null;
4874     }
4875 
4876     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
4877             int flags, List<ResolveInfo> query, int userId) {
4878         if (query != null) {
4879             final int N = query.size();
4880             if (N == 1) {
4881                 return query.get(0);
4882             } else if (N > 1) {
4883                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4884                 // If there is more than one activity with the same priority,
4885                 // then let the user decide between them.
4886                 ResolveInfo r0 = query.get(0);
4887                 ResolveInfo r1 = query.get(1);
4888                 if (DEBUG_INTENT_MATCHING || debug) {
4889                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
4890                             + r1.activityInfo.name + "=" + r1.priority);
4891                 }
4892                 // If the first activity has a higher priority, or a different
4893                 // default, then it is always desirable to pick it.
4894                 if (r0.priority != r1.priority
4895                         || r0.preferredOrder != r1.preferredOrder
4896                         || r0.isDefault != r1.isDefault) {
4897                     return query.get(0);
4898                 }
4899                 // If we have saved a preference for a preferred activity for
4900                 // this Intent, use that.
4901                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
4902                         flags, query, r0.priority, true, false, debug, userId);
4903                 if (ri != null) {
4904                     return ri;
4905                 }
4906                 ri = new ResolveInfo(mResolveInfo);
4907                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
4908                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
4909                 // If all of the options come from the same package, show the application's
4910                 // label and icon instead of the generic resolver's.
4911                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
4912                 // and then throw away the ResolveInfo itself, meaning that the caller loses
4913                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
4914                 // a fallback for this case; we only set the target package's resources on
4915                 // the ResolveInfo, not the ActivityInfo.
4916                 final String intentPackage = intent.getPackage();
4917                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
4918                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
4919                     ri.resolvePackageName = intentPackage;
4920                     if (userNeedsBadging(userId)) {
4921                         ri.noResourceId = true;
4922                     } else {
4923                         ri.icon = appi.icon;
4924                     }
4925                     ri.iconResourceId = appi.icon;
4926                     ri.labelRes = appi.labelRes;
4927                 }
4928                 ri.activityInfo.applicationInfo = new ApplicationInfo(
4929                         ri.activityInfo.applicationInfo);
4930                 if (userId != 0) {
4931                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
4932                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
4933                 }
4934                 // Make sure that the resolver is displayable in car mode
4935                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
4936                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
4937                 return ri;
4938             }
4939         }
4940         return null;
4941     }
4942 
4943     /**
4944      * Return true if the given list is not empty and all of its contents have
4945      * an activityInfo with the given package name.
4946      */
4947     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
4948         if (ArrayUtils.isEmpty(list)) {
4949             return false;
4950         }
4951         for (int i = 0, N = list.size(); i < N; i++) {
4952             final ResolveInfo ri = list.get(i);
4953             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
4954             if (ai == null || !packageName.equals(ai.packageName)) {
4955                 return false;
4956             }
4957         }
4958         return true;
4959     }
4960 
4961     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
4962             int flags, List<ResolveInfo> query, boolean debug, int userId) {
4963         final int N = query.size();
4964         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
4965                 .get(userId);
4966         // Get the list of persistent preferred activities that handle the intent
4967         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
4968         List<PersistentPreferredActivity> pprefs = ppir != null
4969                 ? ppir.queryIntent(intent, resolvedType,
4970                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4971                 : null;
4972         if (pprefs != null && pprefs.size() > 0) {
4973             final int M = pprefs.size();
4974             for (int i=0; i<M; i++) {
4975                 final PersistentPreferredActivity ppa = pprefs.get(i);
4976                 if (DEBUG_PREFERRED || debug) {
4977                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4978                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4979                             + "\n  component=" + ppa.mComponent);
4980                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4981                 }
4982                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4983                         flags | MATCH_DISABLED_COMPONENTS, userId);
4984                 if (DEBUG_PREFERRED || debug) {
4985                     Slog.v(TAG, "Found persistent preferred activity:");
4986                     if (ai != null) {
4987                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4988                     } else {
4989                         Slog.v(TAG, "  null");
4990                     }
4991                 }
4992                 if (ai == null) {
4993                     // This previously registered persistent preferred activity
4994                     // component is no longer known. Ignore it and do NOT remove it.
4995                     continue;
4996                 }
4997                 for (int j=0; j<N; j++) {
4998                     final ResolveInfo ri = query.get(j);
4999                     if (!ri.activityInfo.applicationInfo.packageName
5000                             .equals(ai.applicationInfo.packageName)) {
5001                         continue;
5002                     }
5003                     if (!ri.activityInfo.name.equals(ai.name)) {
5004                         continue;
5005                     }
5006                     //  Found a persistent preference that can handle the intent.
5007                     if (DEBUG_PREFERRED || debug) {
5008                         Slog.v(TAG, "Returning persistent preferred activity: " +
5009                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5010                     }
5011                     return ri;
5012                 }
5013             }
5014         }
5015         return null;
5016     }
5017 
5018     // TODO: handle preferred activities missing while user has amnesia
5019     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5020             List<ResolveInfo> query, int priority, boolean always,
5021             boolean removeMatches, boolean debug, int userId) {
5022         if (!sUserManager.exists(userId)) return null;
5023         flags = updateFlagsForResolve(flags, userId, intent);
5024         // writer
5025         synchronized (mPackages) {
5026             if (intent.getSelector() != null) {
5027                 intent = intent.getSelector();
5028             }
5029             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
5030 
5031             // Try to find a matching persistent preferred activity.
5032             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5033                     debug, userId);
5034 
5035             // If a persistent preferred activity matched, use it.
5036             if (pri != null) {
5037                 return pri;
5038             }
5039 
5040             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5041             // Get the list of preferred activities that handle the intent
5042             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5043             List<PreferredActivity> prefs = pir != null
5044                     ? pir.queryIntent(intent, resolvedType,
5045                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
5046                     : null;
5047             if (prefs != null && prefs.size() > 0) {
5048                 boolean changed = false;
5049                 try {
5050                     // First figure out how good the original match set is.
5051                     // We will only allow preferred activities that came
5052                     // from the same match quality.
5053                     int match = 0;
5054 
5055                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5056 
5057                     final int N = query.size();
5058                     for (int j=0; j<N; j++) {
5059                         final ResolveInfo ri = query.get(j);
5060                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5061                                 + ": 0x" + Integer.toHexString(match));
5062                         if (ri.match > match) {
5063                             match = ri.match;
5064                         }
5065                     }
5066 
5067                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5068                             + Integer.toHexString(match));
5069 
5070                     match &= IntentFilter.MATCH_CATEGORY_MASK;
5071                     final int M = prefs.size();
5072                     for (int i=0; i<M; i++) {
5073                         final PreferredActivity pa = prefs.get(i);
5074                         if (DEBUG_PREFERRED || debug) {
5075                             Slog.v(TAG, "Checking PreferredActivity ds="
5076                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
5077                                     + "\n  component=" + pa.mPref.mComponent);
5078                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5079                         }
5080                         if (pa.mPref.mMatch != match) {
5081                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
5082                                     + Integer.toHexString(pa.mPref.mMatch));
5083                             continue;
5084                         }
5085                         // If it's not an "always" type preferred activity and that's what we're
5086                         // looking for, skip it.
5087                         if (always && !pa.mPref.mAlways) {
5088                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
5089                             continue;
5090                         }
5091                         final ActivityInfo ai = getActivityInfo(
5092                                 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
5093                                         | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
5094                                 userId);
5095                         if (DEBUG_PREFERRED || debug) {
5096                             Slog.v(TAG, "Found preferred activity:");
5097                             if (ai != null) {
5098                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5099                             } else {
5100                                 Slog.v(TAG, "  null");
5101                             }
5102                         }
5103                         if (ai == null) {
5104                             // This previously registered preferred activity
5105                             // component is no longer known.  Most likely an update
5106                             // to the app was installed and in the new version this
5107                             // component no longer exists.  Clean it up by removing
5108                             // it from the preferred activities list, and skip it.
5109                             Slog.w(TAG, "Removing dangling preferred activity: "
5110                                     + pa.mPref.mComponent);
5111                             pir.removeFilter(pa);
5112                             changed = true;
5113                             continue;
5114                         }
5115                         for (int j=0; j<N; j++) {
5116                             final ResolveInfo ri = query.get(j);
5117                             if (!ri.activityInfo.applicationInfo.packageName
5118                                     .equals(ai.applicationInfo.packageName)) {
5119                                 continue;
5120                             }
5121                             if (!ri.activityInfo.name.equals(ai.name)) {
5122                                 continue;
5123                             }
5124 
5125                             if (removeMatches) {
5126                                 pir.removeFilter(pa);
5127                                 changed = true;
5128                                 if (DEBUG_PREFERRED) {
5129                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
5130                                 }
5131                                 break;
5132                             }
5133 
5134                             // Okay we found a previously set preferred or last chosen app.
5135                             // If the result set is different from when this
5136                             // was created, we need to clear it and re-ask the
5137                             // user their preference, if we're looking for an "always" type entry.
5138                             if (always && !pa.mPref.sameSet(query)) {
5139                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
5140                                         + intent + " type " + resolvedType);
5141                                 if (DEBUG_PREFERRED) {
5142                                     Slog.v(TAG, "Removing preferred activity since set changed "
5143                                             + pa.mPref.mComponent);
5144                                 }
5145                                 pir.removeFilter(pa);
5146                                 // Re-add the filter as a "last chosen" entry (!always)
5147                                 PreferredActivity lastChosen = new PreferredActivity(
5148                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
5149                                 pir.addFilter(lastChosen);
5150                                 changed = true;
5151                                 return null;
5152                             }
5153 
5154                             // Yay! Either the set matched or we're looking for the last chosen
5155                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
5156                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5157                             return ri;
5158                         }
5159                     }
5160                 } finally {
5161                     if (changed) {
5162                         if (DEBUG_PREFERRED) {
5163                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
5164                         }
5165                         scheduleWritePackageRestrictionsLocked(userId);
5166                     }
5167                 }
5168             }
5169         }
5170         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
5171         return null;
5172     }
5173 
5174     /*
5175      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
5176      */
5177     @Override
5178     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
5179             int targetUserId) {
5180         mContext.enforceCallingOrSelfPermission(
5181                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
5182         List<CrossProfileIntentFilter> matches =
5183                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
5184         if (matches != null) {
5185             int size = matches.size();
5186             for (int i = 0; i < size; i++) {
5187                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
5188             }
5189         }
5190         if (hasWebURI(intent)) {
5191             // cross-profile app linking works only towards the parent.
5192             final UserInfo parent = getProfileParent(sourceUserId);
5193             synchronized(mPackages) {
5194                 int flags = updateFlagsForResolve(0, parent.id, intent);
5195                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
5196                         intent, resolvedType, flags, sourceUserId, parent.id);
5197                 return xpDomainInfo != null;
5198             }
5199         }
5200         return false;
5201     }
5202 
5203     private UserInfo getProfileParent(int userId) {
5204         final long identity = Binder.clearCallingIdentity();
5205         try {
5206             return sUserManager.getProfileParent(userId);
5207         } finally {
5208             Binder.restoreCallingIdentity(identity);
5209         }
5210     }
5211 
5212     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
5213             String resolvedType, int userId) {
5214         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
5215         if (resolver != null) {
5216             return resolver.queryIntent(intent, resolvedType, false, userId);
5217         }
5218         return null;
5219     }
5220 
5221     @Override
5222     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
5223             String resolvedType, int flags, int userId) {
5224         try {
5225             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5226 
5227             return new ParceledListSlice<>(
5228                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
5229         } finally {
5230             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5231         }
5232     }
5233 
5234     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5235             String resolvedType, int flags, int userId) {
5236         if (!sUserManager.exists(userId)) return Collections.emptyList();
5237         flags = updateFlagsForResolve(flags, userId, intent);
5238         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5239                 false /* requireFullPermission */, false /* checkShell */,
5240                 "query intent activities");
5241         ComponentName comp = intent.getComponent();
5242         if (comp == null) {
5243             if (intent.getSelector() != null) {
5244                 intent = intent.getSelector();
5245                 comp = intent.getComponent();
5246             }
5247         }
5248 
5249         if (comp != null) {
5250             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5251             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
5252             if (ai != null) {
5253                 final ResolveInfo ri = new ResolveInfo();
5254                 ri.activityInfo = ai;
5255                 list.add(ri);
5256             }
5257             return list;
5258         }
5259 
5260         // reader
5261         synchronized (mPackages) {
5262             final String pkgName = intent.getPackage();
5263             if (pkgName == null) {
5264                 List<CrossProfileIntentFilter> matchingFilters =
5265                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
5266                 // Check for results that need to skip the current profile.
5267                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
5268                         resolvedType, flags, userId);
5269                 if (xpResolveInfo != null) {
5270                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
5271                     result.add(xpResolveInfo);
5272                     return filterIfNotSystemUser(result, userId);
5273                 }
5274 
5275                 // Check for results in the current profile.
5276                 List<ResolveInfo> result = mActivities.queryIntent(
5277                         intent, resolvedType, flags, userId);
5278                 result = filterIfNotSystemUser(result, userId);
5279 
5280                 // Check for cross profile results.
5281                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
5282                 xpResolveInfo = queryCrossProfileIntents(
5283                         matchingFilters, intent, resolvedType, flags, userId,
5284                         hasNonNegativePriorityResult);
5285                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
5286                     boolean isVisibleToUser = filterIfNotSystemUser(
5287                             Collections.singletonList(xpResolveInfo), userId).size() > 0;
5288                     if (isVisibleToUser) {
5289                         result.add(xpResolveInfo);
5290                         Collections.sort(result, mResolvePrioritySorter);
5291                     }
5292                 }
5293                 if (hasWebURI(intent)) {
5294                     CrossProfileDomainInfo xpDomainInfo = null;
5295                     final UserInfo parent = getProfileParent(userId);
5296                     if (parent != null) {
5297                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
5298                                 flags, userId, parent.id);
5299                     }
5300                     if (xpDomainInfo != null) {
5301                         if (xpResolveInfo != null) {
5302                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
5303                             // in the result.
5304                             result.remove(xpResolveInfo);
5305                         }
5306                         if (result.size() == 0) {
5307                             result.add(xpDomainInfo.resolveInfo);
5308                             return result;
5309                         }
5310                     } else if (result.size() <= 1) {
5311                         return result;
5312                     }
5313                     result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
5314                             xpDomainInfo, userId);
5315                     Collections.sort(result, mResolvePrioritySorter);
5316                 }
5317                 return result;
5318             }
5319             final PackageParser.Package pkg = mPackages.get(pkgName);
5320             if (pkg != null) {
5321                 return filterIfNotSystemUser(
5322                         mActivities.queryIntentForPackage(
5323                                 intent, resolvedType, flags, pkg.activities, userId),
5324                         userId);
5325             }
5326             return new ArrayList<ResolveInfo>();
5327         }
5328     }
5329 
5330     private static class CrossProfileDomainInfo {
5331         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
5332         ResolveInfo resolveInfo;
5333         /* Best domain verification status of the activities found in the other profile */
5334         int bestDomainVerificationStatus;
5335     }
5336 
5337     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5338             String resolvedType, int flags, int sourceUserId, int parentUserId) {
5339         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
5340                 sourceUserId)) {
5341             return null;
5342         }
5343         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5344                 resolvedType, flags, parentUserId);
5345 
5346         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
5347             return null;
5348         }
5349         CrossProfileDomainInfo result = null;
5350         int size = resultTargetUser.size();
5351         for (int i = 0; i < size; i++) {
5352             ResolveInfo riTargetUser = resultTargetUser.get(i);
5353             // Intent filter verification is only for filters that specify a host. So don't return
5354             // those that handle all web uris.
5355             if (riTargetUser.handleAllWebDataURI) {
5356                 continue;
5357             }
5358             String packageName = riTargetUser.activityInfo.packageName;
5359             PackageSetting ps = mSettings.mPackages.get(packageName);
5360             if (ps == null) {
5361                 continue;
5362             }
5363             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
5364             int status = (int)(verificationState >> 32);
5365             if (result == null) {
5366                 result = new CrossProfileDomainInfo();
5367                 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5368                         sourceUserId, parentUserId);
5369                 result.bestDomainVerificationStatus = status;
5370             } else {
5371                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5372                         result.bestDomainVerificationStatus);
5373             }
5374         }
5375         // Don't consider matches with status NEVER across profiles.
5376         if (result != null && result.bestDomainVerificationStatus
5377                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5378             return null;
5379         }
5380         return result;
5381     }
5382 
5383     /**
5384      * Verification statuses are ordered from the worse to the best, except for
5385      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5386      */
5387     private int bestDomainVerificationStatus(int status1, int status2) {
5388         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5389             return status2;
5390         }
5391         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5392             return status1;
5393         }
5394         return (int) MathUtils.max(status1, status2);
5395     }
5396 
5397     private boolean isUserEnabled(int userId) {
5398         long callingId = Binder.clearCallingIdentity();
5399         try {
5400             UserInfo userInfo = sUserManager.getUserInfo(userId);
5401             return userInfo != null && userInfo.isEnabled();
5402         } finally {
5403             Binder.restoreCallingIdentity(callingId);
5404         }
5405     }
5406 
5407     /**
5408      * Filter out activities with systemUserOnly flag set, when current user is not System.
5409      *
5410      * @return filtered list
5411      */
5412     private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5413         if (userId == UserHandle.USER_SYSTEM) {
5414             return resolveInfos;
5415         }
5416         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5417             ResolveInfo info = resolveInfos.get(i);
5418             if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5419                 resolveInfos.remove(i);
5420             }
5421         }
5422         return resolveInfos;
5423     }
5424 
5425     /**
5426      * @param resolveInfos list of resolve infos in descending priority order
5427      * @return if the list contains a resolve info with non-negative priority
5428      */
5429     private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5430         return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5431     }
5432 
5433     private static boolean hasWebURI(Intent intent) {
5434         if (intent.getData() == null) {
5435             return false;
5436         }
5437         final String scheme = intent.getScheme();
5438         if (TextUtils.isEmpty(scheme)) {
5439             return false;
5440         }
5441         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5442     }
5443 
5444     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5445             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5446             int userId) {
5447         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5448 
5449         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5450             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5451                     candidates.size());
5452         }
5453 
5454         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5455         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5456         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5457         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5458         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5459         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5460 
5461         synchronized (mPackages) {
5462             final int count = candidates.size();
5463             // First, try to use linked apps. Partition the candidates into four lists:
5464             // one for the final results, one for the "do not use ever", one for "undefined status"
5465             // and finally one for "browser app type".
5466             for (int n=0; n<count; n++) {
5467                 ResolveInfo info = candidates.get(n);
5468                 String packageName = info.activityInfo.packageName;
5469                 PackageSetting ps = mSettings.mPackages.get(packageName);
5470                 if (ps != null) {
5471                     // Add to the special match all list (Browser use case)
5472                     if (info.handleAllWebDataURI) {
5473                         matchAllList.add(info);
5474                         continue;
5475                     }
5476                     // Try to get the status from User settings first
5477                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5478                     int status = (int)(packedStatus >> 32);
5479                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5480                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5481                         if (DEBUG_DOMAIN_VERIFICATION) {
5482                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5483                                     + " : linkgen=" + linkGeneration);
5484                         }
5485                         // Use link-enabled generation as preferredOrder, i.e.
5486                         // prefer newly-enabled over earlier-enabled.
5487                         info.preferredOrder = linkGeneration;
5488                         alwaysList.add(info);
5489                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5490                         if (DEBUG_DOMAIN_VERIFICATION) {
5491                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5492                         }
5493                         neverList.add(info);
5494                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5495                         if (DEBUG_DOMAIN_VERIFICATION) {
5496                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5497                         }
5498                         alwaysAskList.add(info);
5499                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5500                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5501                         if (DEBUG_DOMAIN_VERIFICATION) {
5502                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5503                         }
5504                         undefinedList.add(info);
5505                     }
5506                 }
5507             }
5508 
5509             // We'll want to include browser possibilities in a few cases
5510             boolean includeBrowser = false;
5511 
5512             // First try to add the "always" resolution(s) for the current user, if any
5513             if (alwaysList.size() > 0) {
5514                 result.addAll(alwaysList);
5515             } else {
5516                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
5517                 result.addAll(undefinedList);
5518                 // Maybe add one for the other profile.
5519                 if (xpDomainInfo != null && (
5520                         xpDomainInfo.bestDomainVerificationStatus
5521                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5522                     result.add(xpDomainInfo.resolveInfo);
5523                 }
5524                 includeBrowser = true;
5525             }
5526 
5527             // The presence of any 'always ask' alternatives means we'll also offer browsers.
5528             // If there were 'always' entries their preferred order has been set, so we also
5529             // back that off to make the alternatives equivalent
5530             if (alwaysAskList.size() > 0) {
5531                 for (ResolveInfo i : result) {
5532                     i.preferredOrder = 0;
5533                 }
5534                 result.addAll(alwaysAskList);
5535                 includeBrowser = true;
5536             }
5537 
5538             if (includeBrowser) {
5539                 // Also add browsers (all of them or only the default one)
5540                 if (DEBUG_DOMAIN_VERIFICATION) {
5541                     Slog.v(TAG, "   ...including browsers in candidate set");
5542                 }
5543                 if ((matchFlags & MATCH_ALL) != 0) {
5544                     result.addAll(matchAllList);
5545                 } else {
5546                     // Browser/generic handling case.  If there's a default browser, go straight
5547                     // to that (but only if there is no other higher-priority match).
5548                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5549                     int maxMatchPrio = 0;
5550                     ResolveInfo defaultBrowserMatch = null;
5551                     final int numCandidates = matchAllList.size();
5552                     for (int n = 0; n < numCandidates; n++) {
5553                         ResolveInfo info = matchAllList.get(n);
5554                         // track the highest overall match priority...
5555                         if (info.priority > maxMatchPrio) {
5556                             maxMatchPrio = info.priority;
5557                         }
5558                         // ...and the highest-priority default browser match
5559                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5560                             if (defaultBrowserMatch == null
5561                                     || (defaultBrowserMatch.priority < info.priority)) {
5562                                 if (debug) {
5563                                     Slog.v(TAG, "Considering default browser match " + info);
5564                                 }
5565                                 defaultBrowserMatch = info;
5566                             }
5567                         }
5568                     }
5569                     if (defaultBrowserMatch != null
5570                             && defaultBrowserMatch.priority >= maxMatchPrio
5571                             && !TextUtils.isEmpty(defaultBrowserPackageName))
5572                     {
5573                         if (debug) {
5574                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5575                         }
5576                         result.add(defaultBrowserMatch);
5577                     } else {
5578                         result.addAll(matchAllList);
5579                     }
5580                 }
5581 
5582                 // If there is nothing selected, add all candidates and remove the ones that the user
5583                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5584                 if (result.size() == 0) {
5585                     result.addAll(candidates);
5586                     result.removeAll(neverList);
5587                 }
5588             }
5589         }
5590         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5591             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5592                     result.size());
5593             for (ResolveInfo info : result) {
5594                 Slog.v(TAG, "  + " + info.activityInfo);
5595             }
5596         }
5597         return result;
5598     }
5599 
5600     // Returns a packed value as a long:
5601     //
5602     // high 'int'-sized word: link status: undefined/ask/never/always.
5603     // low 'int'-sized word: relative priority among 'always' results.
getDomainVerificationStatusLPr(PackageSetting ps, int userId)5604     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5605         long result = ps.getDomainVerificationStatusForUser(userId);
5606         // if none available, get the master status
5607         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5608             if (ps.getIntentFilterVerificationInfo() != null) {
5609                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5610             }
5611         }
5612         return result;
5613     }
5614 
querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)5615     private ResolveInfo querySkipCurrentProfileIntents(
5616             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5617             int flags, int sourceUserId) {
5618         if (matchingFilters != null) {
5619             int size = matchingFilters.size();
5620             for (int i = 0; i < size; i ++) {
5621                 CrossProfileIntentFilter filter = matchingFilters.get(i);
5622                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5623                     // Checking if there are activities in the target user that can handle the
5624                     // intent.
5625                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5626                             resolvedType, flags, sourceUserId);
5627                     if (resolveInfo != null) {
5628                         return resolveInfo;
5629                     }
5630                 }
5631             }
5632         }
5633         return null;
5634     }
5635 
5636     // Return matching ResolveInfo in target user if any.
queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId, boolean matchInCurrentProfile)5637     private ResolveInfo queryCrossProfileIntents(
5638             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5639             int flags, int sourceUserId, boolean matchInCurrentProfile) {
5640         if (matchingFilters != null) {
5641             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5642             // match the same intent. For performance reasons, it is better not to
5643             // run queryIntent twice for the same userId
5644             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5645             int size = matchingFilters.size();
5646             for (int i = 0; i < size; i++) {
5647                 CrossProfileIntentFilter filter = matchingFilters.get(i);
5648                 int targetUserId = filter.getTargetUserId();
5649                 boolean skipCurrentProfile =
5650                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5651                 boolean skipCurrentProfileIfNoMatchFound =
5652                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5653                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5654                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5655                     // Checking if there are activities in the target user that can handle the
5656                     // intent.
5657                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5658                             resolvedType, flags, sourceUserId);
5659                     if (resolveInfo != null) return resolveInfo;
5660                     alreadyTriedUserIds.put(targetUserId, true);
5661                 }
5662             }
5663         }
5664         return null;
5665     }
5666 
5667     /**
5668      * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5669      * will forward the intent to the filter's target user.
5670      * Otherwise, returns null.
5671      */
createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, String resolvedType, int flags, int sourceUserId)5672     private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5673             String resolvedType, int flags, int sourceUserId) {
5674         int targetUserId = filter.getTargetUserId();
5675         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5676                 resolvedType, flags, targetUserId);
5677         if (resultTargetUser != null && isUserEnabled(targetUserId)) {
5678             // If all the matches in the target profile are suspended, return null.
5679             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
5680                 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
5681                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
5682                     return createForwardingResolveInfoUnchecked(filter, sourceUserId,
5683                             targetUserId);
5684                 }
5685             }
5686         }
5687         return null;
5688     }
5689 
createForwardingResolveInfoUnchecked(IntentFilter filter, int sourceUserId, int targetUserId)5690     private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5691             int sourceUserId, int targetUserId) {
5692         ResolveInfo forwardingResolveInfo = new ResolveInfo();
5693         long ident = Binder.clearCallingIdentity();
5694         boolean targetIsProfile;
5695         try {
5696             targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5697         } finally {
5698             Binder.restoreCallingIdentity(ident);
5699         }
5700         String className;
5701         if (targetIsProfile) {
5702             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5703         } else {
5704             className = FORWARD_INTENT_TO_PARENT;
5705         }
5706         ComponentName forwardingActivityComponentName = new ComponentName(
5707                 mAndroidApplication.packageName, className);
5708         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5709                 sourceUserId);
5710         if (!targetIsProfile) {
5711             forwardingActivityInfo.showUserIcon = targetUserId;
5712             forwardingResolveInfo.noResourceId = true;
5713         }
5714         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5715         forwardingResolveInfo.priority = 0;
5716         forwardingResolveInfo.preferredOrder = 0;
5717         forwardingResolveInfo.match = 0;
5718         forwardingResolveInfo.isDefault = true;
5719         forwardingResolveInfo.filter = filter;
5720         forwardingResolveInfo.targetUserId = targetUserId;
5721         return forwardingResolveInfo;
5722     }
5723 
5724     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)5725     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5726             Intent[] specifics, String[] specificTypes, Intent intent,
5727             String resolvedType, int flags, int userId) {
5728         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
5729                 specificTypes, intent, resolvedType, flags, userId));
5730     }
5731 
queryIntentActivityOptionsInternal(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)5732     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
5733             Intent[] specifics, String[] specificTypes, Intent intent,
5734             String resolvedType, int flags, int userId) {
5735         if (!sUserManager.exists(userId)) return Collections.emptyList();
5736         flags = updateFlagsForResolve(flags, userId, intent);
5737         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5738                 false /* requireFullPermission */, false /* checkShell */,
5739                 "query intent activity options");
5740         final String resultsAction = intent.getAction();
5741 
5742         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
5743                 | PackageManager.GET_RESOLVED_FILTER, userId);
5744 
5745         if (DEBUG_INTENT_MATCHING) {
5746             Log.v(TAG, "Query " + intent + ": " + results);
5747         }
5748 
5749         int specificsPos = 0;
5750         int N;
5751 
5752         // todo: note that the algorithm used here is O(N^2).  This
5753         // isn't a problem in our current environment, but if we start running
5754         // into situations where we have more than 5 or 10 matches then this
5755         // should probably be changed to something smarter...
5756 
5757         // First we go through and resolve each of the specific items
5758         // that were supplied, taking care of removing any corresponding
5759         // duplicate items in the generic resolve list.
5760         if (specifics != null) {
5761             for (int i=0; i<specifics.length; i++) {
5762                 final Intent sintent = specifics[i];
5763                 if (sintent == null) {
5764                     continue;
5765                 }
5766 
5767                 if (DEBUG_INTENT_MATCHING) {
5768                     Log.v(TAG, "Specific #" + i + ": " + sintent);
5769                 }
5770 
5771                 String action = sintent.getAction();
5772                 if (resultsAction != null && resultsAction.equals(action)) {
5773                     // If this action was explicitly requested, then don't
5774                     // remove things that have it.
5775                     action = null;
5776                 }
5777 
5778                 ResolveInfo ri = null;
5779                 ActivityInfo ai = null;
5780 
5781                 ComponentName comp = sintent.getComponent();
5782                 if (comp == null) {
5783                     ri = resolveIntent(
5784                         sintent,
5785                         specificTypes != null ? specificTypes[i] : null,
5786                             flags, userId);
5787                     if (ri == null) {
5788                         continue;
5789                     }
5790                     if (ri == mResolveInfo) {
5791                         // ACK!  Must do something better with this.
5792                     }
5793                     ai = ri.activityInfo;
5794                     comp = new ComponentName(ai.applicationInfo.packageName,
5795                             ai.name);
5796                 } else {
5797                     ai = getActivityInfo(comp, flags, userId);
5798                     if (ai == null) {
5799                         continue;
5800                     }
5801                 }
5802 
5803                 // Look for any generic query activities that are duplicates
5804                 // of this specific one, and remove them from the results.
5805                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5806                 N = results.size();
5807                 int j;
5808                 for (j=specificsPos; j<N; j++) {
5809                     ResolveInfo sri = results.get(j);
5810                     if ((sri.activityInfo.name.equals(comp.getClassName())
5811                             && sri.activityInfo.applicationInfo.packageName.equals(
5812                                     comp.getPackageName()))
5813                         || (action != null && sri.filter.matchAction(action))) {
5814                         results.remove(j);
5815                         if (DEBUG_INTENT_MATCHING) Log.v(
5816                             TAG, "Removing duplicate item from " + j
5817                             + " due to specific " + specificsPos);
5818                         if (ri == null) {
5819                             ri = sri;
5820                         }
5821                         j--;
5822                         N--;
5823                     }
5824                 }
5825 
5826                 // Add this specific item to its proper place.
5827                 if (ri == null) {
5828                     ri = new ResolveInfo();
5829                     ri.activityInfo = ai;
5830                 }
5831                 results.add(specificsPos, ri);
5832                 ri.specificIndex = i;
5833                 specificsPos++;
5834             }
5835         }
5836 
5837         // Now we go through the remaining generic results and remove any
5838         // duplicate actions that are found here.
5839         N = results.size();
5840         for (int i=specificsPos; i<N-1; i++) {
5841             final ResolveInfo rii = results.get(i);
5842             if (rii.filter == null) {
5843                 continue;
5844             }
5845 
5846             // Iterate over all of the actions of this result's intent
5847             // filter...  typically this should be just one.
5848             final Iterator<String> it = rii.filter.actionsIterator();
5849             if (it == null) {
5850                 continue;
5851             }
5852             while (it.hasNext()) {
5853                 final String action = it.next();
5854                 if (resultsAction != null && resultsAction.equals(action)) {
5855                     // If this action was explicitly requested, then don't
5856                     // remove things that have it.
5857                     continue;
5858                 }
5859                 for (int j=i+1; j<N; j++) {
5860                     final ResolveInfo rij = results.get(j);
5861                     if (rij.filter != null && rij.filter.hasAction(action)) {
5862                         results.remove(j);
5863                         if (DEBUG_INTENT_MATCHING) Log.v(
5864                             TAG, "Removing duplicate item from " + j
5865                             + " due to action " + action + " at " + i);
5866                         j--;
5867                         N--;
5868                     }
5869                 }
5870             }
5871 
5872             // If the caller didn't request filter information, drop it now
5873             // so we don't have to marshall/unmarshall it.
5874             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5875                 rii.filter = null;
5876             }
5877         }
5878 
5879         // Filter out the caller activity if so requested.
5880         if (caller != null) {
5881             N = results.size();
5882             for (int i=0; i<N; i++) {
5883                 ActivityInfo ainfo = results.get(i).activityInfo;
5884                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
5885                         && caller.getClassName().equals(ainfo.name)) {
5886                     results.remove(i);
5887                     break;
5888                 }
5889             }
5890         }
5891 
5892         // If the caller didn't request filter information,
5893         // drop them now so we don't have to
5894         // marshall/unmarshall it.
5895         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5896             N = results.size();
5897             for (int i=0; i<N; i++) {
5898                 results.get(i).filter = null;
5899             }
5900         }
5901 
5902         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
5903         return results;
5904     }
5905 
5906     @Override
queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)5907     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
5908             String resolvedType, int flags, int userId) {
5909         return new ParceledListSlice<>(
5910                 queryIntentReceiversInternal(intent, resolvedType, flags, userId));
5911     }
5912 
queryIntentReceiversInternal(Intent intent, String resolvedType, int flags, int userId)5913     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
5914             String resolvedType, int flags, int userId) {
5915         if (!sUserManager.exists(userId)) return Collections.emptyList();
5916         flags = updateFlagsForResolve(flags, userId, intent);
5917         ComponentName comp = intent.getComponent();
5918         if (comp == null) {
5919             if (intent.getSelector() != null) {
5920                 intent = intent.getSelector();
5921                 comp = intent.getComponent();
5922             }
5923         }
5924         if (comp != null) {
5925             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5926             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
5927             if (ai != null) {
5928                 ResolveInfo ri = new ResolveInfo();
5929                 ri.activityInfo = ai;
5930                 list.add(ri);
5931             }
5932             return list;
5933         }
5934 
5935         // reader
5936         synchronized (mPackages) {
5937             String pkgName = intent.getPackage();
5938             if (pkgName == null) {
5939                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
5940             }
5941             final PackageParser.Package pkg = mPackages.get(pkgName);
5942             if (pkg != null) {
5943                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
5944                         userId);
5945             }
5946             return Collections.emptyList();
5947         }
5948     }
5949 
5950     @Override
resolveService(Intent intent, String resolvedType, int flags, int userId)5951     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
5952         if (!sUserManager.exists(userId)) return null;
5953         flags = updateFlagsForResolve(flags, userId, intent);
5954         List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
5955         if (query != null) {
5956             if (query.size() >= 1) {
5957                 // If there is more than one service with the same priority,
5958                 // just arbitrarily pick the first one.
5959                 return query.get(0);
5960             }
5961         }
5962         return null;
5963     }
5964 
5965     @Override
queryIntentServices(Intent intent, String resolvedType, int flags, int userId)5966     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
5967             String resolvedType, int flags, int userId) {
5968         return new ParceledListSlice<>(
5969                 queryIntentServicesInternal(intent, resolvedType, flags, userId));
5970     }
5971 
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId)5972     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
5973             String resolvedType, int flags, int userId) {
5974         if (!sUserManager.exists(userId)) return Collections.emptyList();
5975         flags = updateFlagsForResolve(flags, userId, intent);
5976         ComponentName comp = intent.getComponent();
5977         if (comp == null) {
5978             if (intent.getSelector() != null) {
5979                 intent = intent.getSelector();
5980                 comp = intent.getComponent();
5981             }
5982         }
5983         if (comp != null) {
5984             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5985             final ServiceInfo si = getServiceInfo(comp, flags, userId);
5986             if (si != null) {
5987                 final ResolveInfo ri = new ResolveInfo();
5988                 ri.serviceInfo = si;
5989                 list.add(ri);
5990             }
5991             return list;
5992         }
5993 
5994         // reader
5995         synchronized (mPackages) {
5996             String pkgName = intent.getPackage();
5997             if (pkgName == null) {
5998                 return mServices.queryIntent(intent, resolvedType, flags, userId);
5999             }
6000             final PackageParser.Package pkg = mPackages.get(pkgName);
6001             if (pkg != null) {
6002                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
6003                         userId);
6004             }
6005             return Collections.emptyList();
6006         }
6007     }
6008 
6009     @Override
queryIntentContentProviders(Intent intent, String resolvedType, int flags, int userId)6010     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
6011             String resolvedType, int flags, int userId) {
6012         return new ParceledListSlice<>(
6013                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
6014     }
6015 
queryIntentContentProvidersInternal( Intent intent, String resolvedType, int flags, int userId)6016     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
6017             Intent intent, String resolvedType, int flags, int userId) {
6018         if (!sUserManager.exists(userId)) return Collections.emptyList();
6019         flags = updateFlagsForResolve(flags, userId, intent);
6020         ComponentName comp = intent.getComponent();
6021         if (comp == null) {
6022             if (intent.getSelector() != null) {
6023                 intent = intent.getSelector();
6024                 comp = intent.getComponent();
6025             }
6026         }
6027         if (comp != null) {
6028             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6029             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
6030             if (pi != null) {
6031                 final ResolveInfo ri = new ResolveInfo();
6032                 ri.providerInfo = pi;
6033                 list.add(ri);
6034             }
6035             return list;
6036         }
6037 
6038         // reader
6039         synchronized (mPackages) {
6040             String pkgName = intent.getPackage();
6041             if (pkgName == null) {
6042                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
6043             }
6044             final PackageParser.Package pkg = mPackages.get(pkgName);
6045             if (pkg != null) {
6046                 return mProviders.queryIntentForPackage(
6047                         intent, resolvedType, flags, pkg.providers, userId);
6048             }
6049             return Collections.emptyList();
6050         }
6051     }
6052 
6053     @Override
getInstalledPackages(int flags, int userId)6054     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
6055         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6056         flags = updateFlagsForPackage(flags, userId, null);
6057         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6058         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6059                 true /* requireFullPermission */, false /* checkShell */,
6060                 "get installed packages");
6061 
6062         // writer
6063         synchronized (mPackages) {
6064             ArrayList<PackageInfo> list;
6065             if (listUninstalled) {
6066                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
6067                 for (PackageSetting ps : mSettings.mPackages.values()) {
6068                     final PackageInfo pi;
6069                     if (ps.pkg != null) {
6070                         pi = generatePackageInfo(ps, flags, userId);
6071                     } else {
6072                         pi = generatePackageInfo(ps, flags, userId);
6073                     }
6074                     if (pi != null) {
6075                         list.add(pi);
6076                     }
6077                 }
6078             } else {
6079                 list = new ArrayList<PackageInfo>(mPackages.size());
6080                 for (PackageParser.Package p : mPackages.values()) {
6081                     final PackageInfo pi =
6082                             generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
6083                     if (pi != null) {
6084                         list.add(pi);
6085                     }
6086                 }
6087             }
6088 
6089             return new ParceledListSlice<PackageInfo>(list);
6090         }
6091     }
6092 
addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)6093     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
6094             String[] permissions, boolean[] tmp, int flags, int userId) {
6095         int numMatch = 0;
6096         final PermissionsState permissionsState = ps.getPermissionsState();
6097         for (int i=0; i<permissions.length; i++) {
6098             final String permission = permissions[i];
6099             if (permissionsState.hasPermission(permission, userId)) {
6100                 tmp[i] = true;
6101                 numMatch++;
6102             } else {
6103                 tmp[i] = false;
6104             }
6105         }
6106         if (numMatch == 0) {
6107             return;
6108         }
6109         final PackageInfo pi;
6110         if (ps.pkg != null) {
6111             pi = generatePackageInfo(ps, flags, userId);
6112         } else {
6113             pi = generatePackageInfo(ps, flags, userId);
6114         }
6115         // The above might return null in cases of uninstalled apps or install-state
6116         // skew across users/profiles.
6117         if (pi != null) {
6118             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
6119                 if (numMatch == permissions.length) {
6120                     pi.requestedPermissions = permissions;
6121                 } else {
6122                     pi.requestedPermissions = new String[numMatch];
6123                     numMatch = 0;
6124                     for (int i=0; i<permissions.length; i++) {
6125                         if (tmp[i]) {
6126                             pi.requestedPermissions[numMatch] = permissions[i];
6127                             numMatch++;
6128                         }
6129                     }
6130                 }
6131             }
6132             list.add(pi);
6133         }
6134     }
6135 
6136     @Override
getPackagesHoldingPermissions( String[] permissions, int flags, int userId)6137     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
6138             String[] permissions, int flags, int userId) {
6139         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6140         flags = updateFlagsForPackage(flags, userId, permissions);
6141         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6142 
6143         // writer
6144         synchronized (mPackages) {
6145             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
6146             boolean[] tmpBools = new boolean[permissions.length];
6147             if (listUninstalled) {
6148                 for (PackageSetting ps : mSettings.mPackages.values()) {
6149                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
6150                 }
6151             } else {
6152                 for (PackageParser.Package pkg : mPackages.values()) {
6153                     PackageSetting ps = (PackageSetting)pkg.mExtras;
6154                     if (ps != null) {
6155                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
6156                                 userId);
6157                     }
6158                 }
6159             }
6160 
6161             return new ParceledListSlice<PackageInfo>(list);
6162         }
6163     }
6164 
6165     @Override
getInstalledApplications(int flags, int userId)6166     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
6167         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6168         flags = updateFlagsForApplication(flags, userId, null);
6169         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6170 
6171         // writer
6172         synchronized (mPackages) {
6173             ArrayList<ApplicationInfo> list;
6174             if (listUninstalled) {
6175                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
6176                 for (PackageSetting ps : mSettings.mPackages.values()) {
6177                     ApplicationInfo ai;
6178                     if (ps.pkg != null) {
6179                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
6180                                 ps.readUserState(userId), userId);
6181                     } else {
6182                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
6183                     }
6184                     if (ai != null) {
6185                         list.add(ai);
6186                     }
6187                 }
6188             } else {
6189                 list = new ArrayList<ApplicationInfo>(mPackages.size());
6190                 for (PackageParser.Package p : mPackages.values()) {
6191                     if (p.mExtras != null) {
6192                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6193                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
6194                         if (ai != null) {
6195                             list.add(ai);
6196                         }
6197                     }
6198                 }
6199             }
6200 
6201             return new ParceledListSlice<ApplicationInfo>(list);
6202         }
6203     }
6204 
6205     @Override
getEphemeralApplications(int userId)6206     public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
6207         if (DISABLE_EPHEMERAL_APPS) {
6208             return null;
6209         }
6210 
6211         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6212                 "getEphemeralApplications");
6213         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6214                 true /* requireFullPermission */, false /* checkShell */,
6215                 "getEphemeralApplications");
6216         synchronized (mPackages) {
6217             List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
6218                     .getEphemeralApplicationsLPw(userId);
6219             if (ephemeralApps != null) {
6220                 return new ParceledListSlice<>(ephemeralApps);
6221             }
6222         }
6223         return null;
6224     }
6225 
6226     @Override
isEphemeralApplication(String packageName, int userId)6227     public boolean isEphemeralApplication(String packageName, int userId) {
6228         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6229                 true /* requireFullPermission */, false /* checkShell */,
6230                 "isEphemeral");
6231         if (DISABLE_EPHEMERAL_APPS) {
6232             return false;
6233         }
6234 
6235         if (!isCallerSameApp(packageName)) {
6236             return false;
6237         }
6238         synchronized (mPackages) {
6239             PackageParser.Package pkg = mPackages.get(packageName);
6240             if (pkg != null) {
6241                 return pkg.applicationInfo.isEphemeralApp();
6242             }
6243         }
6244         return false;
6245     }
6246 
6247     @Override
getEphemeralApplicationCookie(String packageName, int userId)6248     public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
6249         if (DISABLE_EPHEMERAL_APPS) {
6250             return null;
6251         }
6252 
6253         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6254                 true /* requireFullPermission */, false /* checkShell */,
6255                 "getCookie");
6256         if (!isCallerSameApp(packageName)) {
6257             return null;
6258         }
6259         synchronized (mPackages) {
6260             return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
6261                     packageName, userId);
6262         }
6263     }
6264 
6265     @Override
setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId)6266     public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
6267         if (DISABLE_EPHEMERAL_APPS) {
6268             return true;
6269         }
6270 
6271         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6272                 true /* requireFullPermission */, true /* checkShell */,
6273                 "setCookie");
6274         if (!isCallerSameApp(packageName)) {
6275             return false;
6276         }
6277         synchronized (mPackages) {
6278             return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
6279                     packageName, cookie, userId);
6280         }
6281     }
6282 
6283     @Override
getEphemeralApplicationIcon(String packageName, int userId)6284     public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
6285         if (DISABLE_EPHEMERAL_APPS) {
6286             return null;
6287         }
6288 
6289         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6290                 "getEphemeralApplicationIcon");
6291         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6292                 true /* requireFullPermission */, false /* checkShell */,
6293                 "getEphemeralApplicationIcon");
6294         synchronized (mPackages) {
6295             return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
6296                     packageName, userId);
6297         }
6298     }
6299 
isCallerSameApp(String packageName)6300     private boolean isCallerSameApp(String packageName) {
6301         PackageParser.Package pkg = mPackages.get(packageName);
6302         return pkg != null
6303                 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
6304     }
6305 
6306     @Override
getPersistentApplications(int flags)6307     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
6308         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
6309     }
6310 
getPersistentApplicationsInternal(int flags)6311     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
6312         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
6313 
6314         // reader
6315         synchronized (mPackages) {
6316             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
6317             final int userId = UserHandle.getCallingUserId();
6318             while (i.hasNext()) {
6319                 final PackageParser.Package p = i.next();
6320                 if (p.applicationInfo == null) continue;
6321 
6322                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
6323                         && !p.applicationInfo.isDirectBootAware();
6324                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
6325                         && p.applicationInfo.isDirectBootAware();
6326 
6327                 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
6328                         && (!mSafeMode || isSystemApp(p))
6329                         && (matchesUnaware || matchesAware)) {
6330                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
6331                     if (ps != null) {
6332                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6333                                 ps.readUserState(userId), userId);
6334                         if (ai != null) {
6335                             finalList.add(ai);
6336                         }
6337                     }
6338                 }
6339             }
6340         }
6341 
6342         return finalList;
6343     }
6344 
6345     @Override
resolveContentProvider(String name, int flags, int userId)6346     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
6347         if (!sUserManager.exists(userId)) return null;
6348         flags = updateFlagsForComponent(flags, userId, name);
6349         // reader
6350         synchronized (mPackages) {
6351             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
6352             PackageSetting ps = provider != null
6353                     ? mSettings.mPackages.get(provider.owner.packageName)
6354                     : null;
6355             return ps != null
6356                     && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
6357                     ? PackageParser.generateProviderInfo(provider, flags,
6358                             ps.readUserState(userId), userId)
6359                     : null;
6360         }
6361     }
6362 
6363     /**
6364      * @deprecated
6365      */
6366     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)6367     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
6368         // reader
6369         synchronized (mPackages) {
6370             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
6371                     .entrySet().iterator();
6372             final int userId = UserHandle.getCallingUserId();
6373             while (i.hasNext()) {
6374                 Map.Entry<String, PackageParser.Provider> entry = i.next();
6375                 PackageParser.Provider p = entry.getValue();
6376                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6377 
6378                 if (ps != null && p.syncable
6379                         && (!mSafeMode || (p.info.applicationInfo.flags
6380                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
6381                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
6382                             ps.readUserState(userId), userId);
6383                     if (info != null) {
6384                         outNames.add(entry.getKey());
6385                         outInfo.add(info);
6386                     }
6387                 }
6388             }
6389         }
6390     }
6391 
6392     @Override
queryContentProviders(String processName, int uid, int flags)6393     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
6394             int uid, int flags) {
6395         final int userId = processName != null ? UserHandle.getUserId(uid)
6396                 : UserHandle.getCallingUserId();
6397         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6398         flags = updateFlagsForComponent(flags, userId, processName);
6399 
6400         ArrayList<ProviderInfo> finalList = null;
6401         // reader
6402         synchronized (mPackages) {
6403             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
6404             while (i.hasNext()) {
6405                 final PackageParser.Provider p = i.next();
6406                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6407                 if (ps != null && p.info.authority != null
6408                         && (processName == null
6409                                 || (p.info.processName.equals(processName)
6410                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
6411                         && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
6412                     if (finalList == null) {
6413                         finalList = new ArrayList<ProviderInfo>(3);
6414                     }
6415                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
6416                             ps.readUserState(userId), userId);
6417                     if (info != null) {
6418                         finalList.add(info);
6419                     }
6420                 }
6421             }
6422         }
6423 
6424         if (finalList != null) {
6425             Collections.sort(finalList, mProviderInitOrderSorter);
6426             return new ParceledListSlice<ProviderInfo>(finalList);
6427         }
6428 
6429         return ParceledListSlice.emptyList();
6430     }
6431 
6432     @Override
getInstrumentationInfo(ComponentName name, int flags)6433     public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6434         // reader
6435         synchronized (mPackages) {
6436             final PackageParser.Instrumentation i = mInstrumentation.get(name);
6437             return PackageParser.generateInstrumentationInfo(i, flags);
6438         }
6439     }
6440 
6441     @Override
queryInstrumentation( String targetPackage, int flags)6442     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
6443             String targetPackage, int flags) {
6444         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
6445     }
6446 
queryInstrumentationInternal(String targetPackage, int flags)6447     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
6448             int flags) {
6449         ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
6450 
6451         // reader
6452         synchronized (mPackages) {
6453             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6454             while (i.hasNext()) {
6455                 final PackageParser.Instrumentation p = i.next();
6456                 if (targetPackage == null
6457                         || targetPackage.equals(p.info.targetPackage)) {
6458                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6459                             flags);
6460                     if (ii != null) {
6461                         finalList.add(ii);
6462                     }
6463                 }
6464             }
6465         }
6466 
6467         return finalList;
6468     }
6469 
createIdmapsForPackageLI(PackageParser.Package pkg)6470     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6471         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6472         if (overlays == null) {
6473             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6474             return;
6475         }
6476         for (PackageParser.Package opkg : overlays.values()) {
6477             // Not much to do if idmap fails: we already logged the error
6478             // and we certainly don't want to abort installation of pkg simply
6479             // because an overlay didn't fit properly. For these reasons,
6480             // ignore the return value of createIdmapForPackagePairLI.
6481             createIdmapForPackagePairLI(pkg, opkg);
6482         }
6483     }
6484 
createIdmapForPackagePairLI(PackageParser.Package pkg, PackageParser.Package opkg)6485     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6486             PackageParser.Package opkg) {
6487         if (!opkg.mTrustedOverlay) {
6488             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6489                     opkg.baseCodePath + ": overlay not trusted");
6490             return false;
6491         }
6492         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6493         if (overlaySet == null) {
6494             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6495                     opkg.baseCodePath + " but target package has no known overlays");
6496             return false;
6497         }
6498         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6499         // TODO: generate idmap for split APKs
6500         try {
6501             mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
6502         } catch (InstallerException e) {
6503             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6504                     + opkg.baseCodePath);
6505             return false;
6506         }
6507         PackageParser.Package[] overlayArray =
6508             overlaySet.values().toArray(new PackageParser.Package[0]);
6509         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6510             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6511                 return p1.mOverlayPriority - p2.mOverlayPriority;
6512             }
6513         };
6514         Arrays.sort(overlayArray, cmp);
6515 
6516         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6517         int i = 0;
6518         for (PackageParser.Package p : overlayArray) {
6519             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6520         }
6521         return true;
6522     }
6523 
scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime)6524     private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6525         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6526         try {
6527             scanDirLI(dir, parseFlags, scanFlags, currentTime);
6528         } finally {
6529             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6530         }
6531     }
6532 
scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime)6533     private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6534         final File[] files = dir.listFiles();
6535         if (ArrayUtils.isEmpty(files)) {
6536             Log.d(TAG, "No files in app dir " + dir);
6537             return;
6538         }
6539 
6540         if (DEBUG_PACKAGE_SCANNING) {
6541             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6542                     + " flags=0x" + Integer.toHexString(parseFlags));
6543         }
6544 
6545         for (File file : files) {
6546             final boolean isPackage = (isApkFile(file) || file.isDirectory())
6547                     && !PackageInstallerService.isStageName(file.getName());
6548             if (!isPackage) {
6549                 // Ignore entries which are not packages
6550                 continue;
6551             }
6552             try {
6553                 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6554                         scanFlags, currentTime, null);
6555             } catch (PackageManagerException e) {
6556                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6557 
6558                 // Delete invalid userdata apps
6559                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6560                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6561                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6562                     removeCodePathLI(file);
6563                 }
6564             }
6565         }
6566     }
6567 
getSettingsProblemFile()6568     private static File getSettingsProblemFile() {
6569         File dataDir = Environment.getDataDirectory();
6570         File systemDir = new File(dataDir, "system");
6571         File fname = new File(systemDir, "uiderrors.txt");
6572         return fname;
6573     }
6574 
reportSettingsProblem(int priority, String msg)6575     static void reportSettingsProblem(int priority, String msg) {
6576         logCriticalInfo(priority, msg);
6577     }
6578 
logCriticalInfo(int priority, String msg)6579     static void logCriticalInfo(int priority, String msg) {
6580         Slog.println(priority, TAG, msg);
6581         EventLogTags.writePmCriticalInfo(msg);
6582         try {
6583             File fname = getSettingsProblemFile();
6584             FileOutputStream out = new FileOutputStream(fname, true);
6585             PrintWriter pw = new FastPrintWriter(out);
6586             SimpleDateFormat formatter = new SimpleDateFormat();
6587             String dateString = formatter.format(new Date(System.currentTimeMillis()));
6588             pw.println(dateString + ": " + msg);
6589             pw.close();
6590             FileUtils.setPermissions(
6591                     fname.toString(),
6592                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6593                     -1, -1);
6594         } catch (java.io.IOException e) {
6595         }
6596     }
6597 
getLastModifiedTime(PackageParser.Package pkg, File srcFile)6598     private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
6599         if (srcFile.isDirectory()) {
6600             final File baseFile = new File(pkg.baseCodePath);
6601             long maxModifiedTime = baseFile.lastModified();
6602             if (pkg.splitCodePaths != null) {
6603                 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
6604                     final File splitFile = new File(pkg.splitCodePaths[i]);
6605                     maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
6606                 }
6607             }
6608             return maxModifiedTime;
6609         }
6610         return srcFile.lastModified();
6611     }
6612 
collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, final int policyFlags)6613     private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
6614             final int policyFlags) throws PackageManagerException {
6615         if (ps != null
6616                 && ps.codePath.equals(srcFile)
6617                 && ps.timeStamp == getLastModifiedTime(pkg, srcFile)
6618                 && !isCompatSignatureUpdateNeeded(pkg)
6619                 && !isRecoverSignatureUpdateNeeded(pkg)) {
6620             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6621             KeySetManagerService ksms = mSettings.mKeySetManagerService;
6622             ArraySet<PublicKey> signingKs;
6623             synchronized (mPackages) {
6624                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6625             }
6626             if (ps.signatures.mSignatures != null
6627                     && ps.signatures.mSignatures.length != 0
6628                     && signingKs != null) {
6629                 // Optimization: reuse the existing cached certificates
6630                 // if the package appears to be unchanged.
6631                 pkg.mSignatures = ps.signatures.mSignatures;
6632                 pkg.mSigningKeys = signingKs;
6633                 return;
6634             }
6635 
6636             Slog.w(TAG, "PackageSetting for " + ps.name
6637                     + " is missing signatures.  Collecting certs again to recover them.");
6638         } else {
6639             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
6640         }
6641 
6642         try {
6643             PackageParser.collectCertificates(pkg, policyFlags);
6644         } catch (PackageParserException e) {
6645             throw PackageManagerException.from(e);
6646         }
6647     }
6648 
6649     /**
6650      *  Traces a package scan.
6651      *  @see #scanPackageLI(File, int, int, long, UserHandle)
6652      */
scanPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, long currentTime, UserHandle user)6653     private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
6654             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6655         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6656         try {
6657             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6658         } finally {
6659             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6660         }
6661     }
6662 
6663     /**
6664      *  Scans a package and returns the newly parsed package.
6665      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6666      */
scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)6667     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6668             long currentTime, UserHandle user) throws PackageManagerException {
6669         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6670         PackageParser pp = new PackageParser();
6671         pp.setSeparateProcesses(mSeparateProcesses);
6672         pp.setOnlyCoreApps(mOnlyCore);
6673         pp.setDisplayMetrics(mMetrics);
6674 
6675         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6676             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6677         }
6678 
6679         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
6680         final PackageParser.Package pkg;
6681         try {
6682             pkg = pp.parsePackage(scanFile, parseFlags);
6683         } catch (PackageParserException e) {
6684             throw PackageManagerException.from(e);
6685         } finally {
6686             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6687         }
6688 
6689         return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
6690     }
6691 
6692     /**
6693      *  Scans a package and returns the newly parsed package.
6694      *  @throws PackageManagerException on a parse error.
6695      */
scanPackageLI(PackageParser.Package pkg, File scanFile, final int policyFlags, int scanFlags, long currentTime, UserHandle user)6696     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
6697             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
6698             throws PackageManagerException {
6699         // If the package has children and this is the first dive in the function
6700         // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
6701         // packages (parent and children) would be successfully scanned before the
6702         // actual scan since scanning mutates internal state and we want to atomically
6703         // install the package and its children.
6704         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
6705             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
6706                 scanFlags |= SCAN_CHECK_ONLY;
6707             }
6708         } else {
6709             scanFlags &= ~SCAN_CHECK_ONLY;
6710         }
6711 
6712         // Scan the parent
6713         PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
6714                 scanFlags, currentTime, user);
6715 
6716         // Scan the children
6717         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
6718         for (int i = 0; i < childCount; i++) {
6719             PackageParser.Package childPackage = pkg.childPackages.get(i);
6720             scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
6721                     currentTime, user);
6722         }
6723 
6724 
6725         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
6726             return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
6727         }
6728 
6729         return scannedPkg;
6730     }
6731 
6732     /**
6733      *  Scans a package and returns the newly parsed package.
6734      *  @throws PackageManagerException on a parse error.
6735      */
scanPackageInternalLI(PackageParser.Package pkg, File scanFile, int policyFlags, int scanFlags, long currentTime, UserHandle user)6736     private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
6737             int policyFlags, int scanFlags, long currentTime, UserHandle user)
6738             throws PackageManagerException {
6739         PackageSetting ps = null;
6740         PackageSetting updatedPkg;
6741         // reader
6742         synchronized (mPackages) {
6743             // Look to see if we already know about this package.
6744             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6745             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6746                 // This package has been renamed to its original name.  Let's
6747                 // use that.
6748                 ps = mSettings.peekPackageLPr(oldName);
6749             }
6750             // If there was no original package, see one for the real package name.
6751             if (ps == null) {
6752                 ps = mSettings.peekPackageLPr(pkg.packageName);
6753             }
6754             // Check to see if this package could be hiding/updating a system
6755             // package.  Must look for it either under the original or real
6756             // package name depending on our state.
6757             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6758             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6759 
6760             // If this is a package we don't know about on the system partition, we
6761             // may need to remove disabled child packages on the system partition
6762             // or may need to not add child packages if the parent apk is updated
6763             // on the data partition and no longer defines this child package.
6764             if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6765                 // If this is a parent package for an updated system app and this system
6766                 // app got an OTA update which no longer defines some of the child packages
6767                 // we have to prune them from the disabled system packages.
6768                 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
6769                 if (disabledPs != null) {
6770                     final int scannedChildCount = (pkg.childPackages != null)
6771                             ? pkg.childPackages.size() : 0;
6772                     final int disabledChildCount = disabledPs.childPackageNames != null
6773                             ? disabledPs.childPackageNames.size() : 0;
6774                     for (int i = 0; i < disabledChildCount; i++) {
6775                         String disabledChildPackageName = disabledPs.childPackageNames.get(i);
6776                         boolean disabledPackageAvailable = false;
6777                         for (int j = 0; j < scannedChildCount; j++) {
6778                             PackageParser.Package childPkg = pkg.childPackages.get(j);
6779                             if (childPkg.packageName.equals(disabledChildPackageName)) {
6780                                 disabledPackageAvailable = true;
6781                                 break;
6782                             }
6783                          }
6784                          if (!disabledPackageAvailable) {
6785                              mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
6786                          }
6787                     }
6788                 }
6789             }
6790         }
6791 
6792         boolean updatedPkgBetter = false;
6793         // First check if this is a system package that may involve an update
6794         if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6795             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
6796             // it needs to drop FLAG_PRIVILEGED.
6797             if (locationIsPrivileged(scanFile)) {
6798                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6799             } else {
6800                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6801             }
6802 
6803             if (ps != null && !ps.codePath.equals(scanFile)) {
6804                 // The path has changed from what was last scanned...  check the
6805                 // version of the new path against what we have stored to determine
6806                 // what to do.
6807                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
6808                 if (pkg.mVersionCode <= ps.versionCode) {
6809                     // The system package has been updated and the code path does not match
6810                     // Ignore entry. Skip it.
6811                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
6812                             + " ignored: updated version " + ps.versionCode
6813                             + " better than this " + pkg.mVersionCode);
6814                     if (!updatedPkg.codePath.equals(scanFile)) {
6815                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
6816                                 + ps.name + " changing from " + updatedPkg.codePathString
6817                                 + " to " + scanFile);
6818                         updatedPkg.codePath = scanFile;
6819                         updatedPkg.codePathString = scanFile.toString();
6820                         updatedPkg.resourcePath = scanFile;
6821                         updatedPkg.resourcePathString = scanFile.toString();
6822                     }
6823                     updatedPkg.pkg = pkg;
6824                     updatedPkg.versionCode = pkg.mVersionCode;
6825 
6826                     // Update the disabled system child packages to point to the package too.
6827                     final int childCount = updatedPkg.childPackageNames != null
6828                             ? updatedPkg.childPackageNames.size() : 0;
6829                     for (int i = 0; i < childCount; i++) {
6830                         String childPackageName = updatedPkg.childPackageNames.get(i);
6831                         PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
6832                                 childPackageName);
6833                         if (updatedChildPkg != null) {
6834                             updatedChildPkg.pkg = pkg;
6835                             updatedChildPkg.versionCode = pkg.mVersionCode;
6836                         }
6837                     }
6838 
6839                     throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
6840                             + scanFile + " ignored: updated version " + ps.versionCode
6841                             + " better than this " + pkg.mVersionCode);
6842                 } else {
6843                     // The current app on the system partition is better than
6844                     // what we have updated to on the data partition; switch
6845                     // back to the system partition version.
6846                     // At this point, its safely assumed that package installation for
6847                     // apps in system partition will go through. If not there won't be a working
6848                     // version of the app
6849                     // writer
6850                     synchronized (mPackages) {
6851                         // Just remove the loaded entries from package lists.
6852                         mPackages.remove(ps.name);
6853                     }
6854 
6855                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6856                             + " reverting from " + ps.codePathString
6857                             + ": new version " + pkg.mVersionCode
6858                             + " better than installed " + ps.versionCode);
6859 
6860                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6861                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6862                     synchronized (mInstallLock) {
6863                         args.cleanUpResourcesLI();
6864                     }
6865                     synchronized (mPackages) {
6866                         mSettings.enableSystemPackageLPw(ps.name);
6867                     }
6868                     updatedPkgBetter = true;
6869                 }
6870             }
6871         }
6872 
6873         if (updatedPkg != null) {
6874             // An updated system app will not have the PARSE_IS_SYSTEM flag set
6875             // initially
6876             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
6877 
6878             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
6879             // flag set initially
6880             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
6881                 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
6882             }
6883         }
6884 
6885         // Verify certificates against what was last scanned
6886         collectCertificatesLI(ps, pkg, scanFile, policyFlags);
6887 
6888         /*
6889          * A new system app appeared, but we already had a non-system one of the
6890          * same name installed earlier.
6891          */
6892         boolean shouldHideSystemApp = false;
6893         if (updatedPkg == null && ps != null
6894                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
6895             /*
6896              * Check to make sure the signatures match first. If they don't,
6897              * wipe the installed application and its data.
6898              */
6899             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
6900                     != PackageManager.SIGNATURE_MATCH) {
6901                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
6902                         + " signatures don't match existing userdata copy; removing");
6903                 try (PackageFreezer freezer = freezePackage(pkg.packageName,
6904                         "scanPackageInternalLI")) {
6905                     deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
6906                 }
6907                 ps = null;
6908             } else {
6909                 /*
6910                  * If the newly-added system app is an older version than the
6911                  * already installed version, hide it. It will be scanned later
6912                  * and re-added like an update.
6913                  */
6914                 if (pkg.mVersionCode <= ps.versionCode) {
6915                     shouldHideSystemApp = true;
6916                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
6917                             + " but new version " + pkg.mVersionCode + " better than installed "
6918                             + ps.versionCode + "; hiding system");
6919                 } else {
6920                     /*
6921                      * The newly found system app is a newer version that the
6922                      * one previously installed. Simply remove the
6923                      * already-installed application and replace it with our own
6924                      * while keeping the application data.
6925                      */
6926                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6927                             + " reverting from " + ps.codePathString + ": new version "
6928                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
6929                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6930                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6931                     synchronized (mInstallLock) {
6932                         args.cleanUpResourcesLI();
6933                     }
6934                 }
6935             }
6936         }
6937 
6938         // The apk is forward locked (not public) if its code and resources
6939         // are kept in different files. (except for app in either system or
6940         // vendor path).
6941         // TODO grab this value from PackageSettings
6942         if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6943             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
6944                 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
6945             }
6946         }
6947 
6948         // TODO: extend to support forward-locked splits
6949         String resourcePath = null;
6950         String baseResourcePath = null;
6951         if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
6952             if (ps != null && ps.resourcePathString != null) {
6953                 resourcePath = ps.resourcePathString;
6954                 baseResourcePath = ps.resourcePathString;
6955             } else {
6956                 // Should not happen at all. Just log an error.
6957                 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
6958             }
6959         } else {
6960             resourcePath = pkg.codePath;
6961             baseResourcePath = pkg.baseCodePath;
6962         }
6963 
6964         // Set application objects path explicitly.
6965         pkg.setApplicationVolumeUuid(pkg.volumeUuid);
6966         pkg.setApplicationInfoCodePath(pkg.codePath);
6967         pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
6968         pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
6969         pkg.setApplicationInfoResourcePath(resourcePath);
6970         pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
6971         pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
6972 
6973         // Note that we invoke the following method only if we are about to unpack an application
6974         PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
6975                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
6976 
6977         /*
6978          * If the system app should be overridden by a previously installed
6979          * data, hide the system app now and let the /data/app scan pick it up
6980          * again.
6981          */
6982         if (shouldHideSystemApp) {
6983             synchronized (mPackages) {
6984                 mSettings.disableSystemPackageLPw(pkg.packageName, true);
6985             }
6986         }
6987 
6988         return scannedPkg;
6989     }
6990 
fixProcessName(String defProcessName, String processName, int uid)6991     private static String fixProcessName(String defProcessName,
6992             String processName, int uid) {
6993         if (processName == null) {
6994             return defProcessName;
6995         }
6996         return processName;
6997     }
6998 
verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)6999     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
7000             throws PackageManagerException {
7001         if (pkgSetting.signatures.mSignatures != null) {
7002             // Already existing package. Make sure signatures match
7003             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
7004                     == PackageManager.SIGNATURE_MATCH;
7005             if (!match) {
7006                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
7007                         == PackageManager.SIGNATURE_MATCH;
7008             }
7009             if (!match) {
7010                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
7011                         == PackageManager.SIGNATURE_MATCH;
7012             }
7013             if (!match) {
7014                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
7015                         + pkg.packageName + " signatures do not match the "
7016                         + "previously installed version; ignoring!");
7017             }
7018         }
7019 
7020         // Check for shared user signatures
7021         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
7022             // Already existing package. Make sure signatures match
7023             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7024                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
7025             if (!match) {
7026                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
7027                         == PackageManager.SIGNATURE_MATCH;
7028             }
7029             if (!match) {
7030                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
7031                         == PackageManager.SIGNATURE_MATCH;
7032             }
7033             if (!match) {
7034                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
7035                         "Package " + pkg.packageName
7036                         + " has no signatures that match those in shared user "
7037                         + pkgSetting.sharedUser.name + "; ignoring!");
7038             }
7039         }
7040     }
7041 
7042     /**
7043      * Enforces that only the system UID or root's UID can call a method exposed
7044      * via Binder.
7045      *
7046      * @param message used as message if SecurityException is thrown
7047      * @throws SecurityException if the caller is not system or root
7048      */
enforceSystemOrRoot(String message)7049     private static final void enforceSystemOrRoot(String message) {
7050         final int uid = Binder.getCallingUid();
7051         if (uid != Process.SYSTEM_UID && uid != 0) {
7052             throw new SecurityException(message);
7053         }
7054     }
7055 
7056     @Override
performFstrimIfNeeded()7057     public void performFstrimIfNeeded() {
7058         enforceSystemOrRoot("Only the system can request fstrim");
7059 
7060         // Before everything else, see whether we need to fstrim.
7061         try {
7062             IMountService ms = PackageHelper.getMountService();
7063             if (ms != null) {
7064                 boolean doTrim = false;
7065                 final long interval = android.provider.Settings.Global.getLong(
7066                         mContext.getContentResolver(),
7067                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
7068                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
7069                 if (interval > 0) {
7070                     final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
7071                     if (timeSinceLast > interval) {
7072                         doTrim = true;
7073                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
7074                                 + "; running immediately");
7075                     }
7076                 }
7077                 if (doTrim) {
7078                     if (!isFirstBoot()) {
7079                         try {
7080                             ActivityManagerNative.getDefault().showBootMessage(
7081                                     mContext.getResources().getString(
7082                                             R.string.android_upgrading_fstrim), true);
7083                         } catch (RemoteException e) {
7084                         }
7085                     }
7086                     ms.runMaintenance();
7087                 }
7088             } else {
7089                 Slog.e(TAG, "Mount service unavailable!");
7090             }
7091         } catch (RemoteException e) {
7092             // Can't happen; MountService is local
7093         }
7094     }
7095 
7096     @Override
updatePackagesIfNeeded()7097     public void updatePackagesIfNeeded() {
7098         enforceSystemOrRoot("Only the system can request package update");
7099 
7100         // We need to re-extract after an OTA.
7101         boolean causeUpgrade = isUpgrade();
7102 
7103         // First boot or factory reset.
7104         // Note: we also handle devices that are upgrading to N right now as if it is their
7105         //       first boot, as they do not have profile data.
7106         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
7107 
7108         // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
7109         boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
7110 
7111         if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
7112             return;
7113         }
7114 
7115         List<PackageParser.Package> pkgs;
7116         synchronized (mPackages) {
7117             pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
7118         }
7119 
7120         final long startTime = System.nanoTime();
7121         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
7122                     getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
7123 
7124         final int elapsedTimeSeconds =
7125                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
7126 
7127         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
7128         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
7129         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
7130         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
7131         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
7132     }
7133 
7134     /**
7135      * Performs dexopt on the set of packages in {@code packages} and returns an int array
7136      * containing statistics about the invocation. The array consists of three elements,
7137      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
7138      * and {@code numberOfPackagesFailed}.
7139      */
performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, String compilerFilter)7140     private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
7141             String compilerFilter) {
7142 
7143         int numberOfPackagesVisited = 0;
7144         int numberOfPackagesOptimized = 0;
7145         int numberOfPackagesSkipped = 0;
7146         int numberOfPackagesFailed = 0;
7147         final int numberOfPackagesToDexopt = pkgs.size();
7148 
7149         for (PackageParser.Package pkg : pkgs) {
7150             numberOfPackagesVisited++;
7151 
7152             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
7153                 if (DEBUG_DEXOPT) {
7154                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
7155                 }
7156                 numberOfPackagesSkipped++;
7157                 continue;
7158             }
7159 
7160             if (DEBUG_DEXOPT) {
7161                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
7162                         numberOfPackagesToDexopt + ": " + pkg.packageName);
7163             }
7164 
7165             if (showDialog) {
7166                 try {
7167                     ActivityManagerNative.getDefault().showBootMessage(
7168                             mContext.getResources().getString(R.string.android_upgrading_apk,
7169                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
7170                 } catch (RemoteException e) {
7171                 }
7172             }
7173 
7174             // If the OTA updates a system app which was previously preopted to a non-preopted state
7175             // the app might end up being verified at runtime. That's because by default the apps
7176             // are verify-profile but for preopted apps there's no profile.
7177             // Do a hacky check to ensure that if we have no profiles (a reasonable indication
7178             // that before the OTA the app was preopted) the app gets compiled with a non-profile
7179             // filter (by default interpret-only).
7180             // Note that at this stage unused apps are already filtered.
7181             if (isSystemApp(pkg) &&
7182                     DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
7183                     !Environment.getReferenceProfile(pkg.packageName).exists()) {
7184                 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
7185             }
7186 
7187             // checkProfiles is false to avoid merging profiles during boot which
7188             // might interfere with background compilation (b/28612421).
7189             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
7190             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
7191             // trade-off worth doing to save boot time work.
7192             int dexOptStatus = performDexOptTraced(pkg.packageName,
7193                     false /* checkProfiles */,
7194                     compilerFilter,
7195                     false /* force */);
7196             switch (dexOptStatus) {
7197                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
7198                     numberOfPackagesOptimized++;
7199                     break;
7200                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
7201                     numberOfPackagesSkipped++;
7202                     break;
7203                 case PackageDexOptimizer.DEX_OPT_FAILED:
7204                     numberOfPackagesFailed++;
7205                     break;
7206                 default:
7207                     Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
7208                     break;
7209             }
7210         }
7211 
7212         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
7213                 numberOfPackagesFailed };
7214     }
7215 
7216     @Override
notifyPackageUse(String packageName, int reason)7217     public void notifyPackageUse(String packageName, int reason) {
7218         synchronized (mPackages) {
7219             PackageParser.Package p = mPackages.get(packageName);
7220             if (p == null) {
7221                 return;
7222             }
7223             p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
7224         }
7225     }
7226 
7227     // TODO: this is not used nor needed. Delete it.
7228     @Override
performDexOptIfNeeded(String packageName)7229     public boolean performDexOptIfNeeded(String packageName) {
7230         int dexOptStatus = performDexOptTraced(packageName,
7231                 false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
7232         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7233     }
7234 
7235     @Override
performDexOpt(String packageName, boolean checkProfiles, int compileReason, boolean force)7236     public boolean performDexOpt(String packageName,
7237             boolean checkProfiles, int compileReason, boolean force) {
7238         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7239                 getCompilerFilterForReason(compileReason), force);
7240         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7241     }
7242 
7243     @Override
performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force)7244     public boolean performDexOptMode(String packageName,
7245             boolean checkProfiles, String targetCompilerFilter, boolean force) {
7246         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7247                 targetCompilerFilter, force);
7248         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7249     }
7250 
performDexOptTraced(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force)7251     private int performDexOptTraced(String packageName,
7252                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
7253         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7254         try {
7255             return performDexOptInternal(packageName, checkProfiles,
7256                     targetCompilerFilter, force);
7257         } finally {
7258             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7259         }
7260     }
7261 
7262     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
7263     // if the package can now be considered up to date for the given filter.
performDexOptInternal(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force)7264     private int performDexOptInternal(String packageName,
7265                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
7266         PackageParser.Package p;
7267         synchronized (mPackages) {
7268             p = mPackages.get(packageName);
7269             if (p == null) {
7270                 // Package could not be found. Report failure.
7271                 return PackageDexOptimizer.DEX_OPT_FAILED;
7272             }
7273             mPackageUsage.maybeWriteAsync(mPackages);
7274             mCompilerStats.maybeWriteAsync();
7275         }
7276         long callingId = Binder.clearCallingIdentity();
7277         try {
7278             synchronized (mInstallLock) {
7279                 return performDexOptInternalWithDependenciesLI(p, checkProfiles,
7280                         targetCompilerFilter, force);
7281             }
7282         } finally {
7283             Binder.restoreCallingIdentity(callingId);
7284         }
7285     }
7286 
getOptimizablePackages()7287     public ArraySet<String> getOptimizablePackages() {
7288         ArraySet<String> pkgs = new ArraySet<String>();
7289         synchronized (mPackages) {
7290             for (PackageParser.Package p : mPackages.values()) {
7291                 if (PackageDexOptimizer.canOptimizePackage(p)) {
7292                     pkgs.add(p.packageName);
7293                 }
7294             }
7295         }
7296         return pkgs;
7297     }
7298 
performDexOptInternalWithDependenciesLI(PackageParser.Package p, boolean checkProfiles, String targetCompilerFilter, boolean force)7299     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
7300             boolean checkProfiles, String targetCompilerFilter,
7301             boolean force) {
7302         // Select the dex optimizer based on the force parameter.
7303         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
7304         //       allocate an object here.
7305         PackageDexOptimizer pdo = force
7306                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
7307                 : mPackageDexOptimizer;
7308 
7309         // Optimize all dependencies first. Note: we ignore the return value and march on
7310         // on errors.
7311         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
7312         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
7313         if (!deps.isEmpty()) {
7314             for (PackageParser.Package depPackage : deps) {
7315                 // TODO: Analyze and investigate if we (should) profile libraries.
7316                 // Currently this will do a full compilation of the library by default.
7317                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
7318                         false /* checkProfiles */,
7319                         getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
7320                         getOrCreateCompilerPackageStats(depPackage));
7321             }
7322         }
7323         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
7324                 targetCompilerFilter, getOrCreateCompilerPackageStats(p));
7325     }
7326 
findSharedNonSystemLibraries(PackageParser.Package p)7327     Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
7328         if (p.usesLibraries != null || p.usesOptionalLibraries != null) {
7329             ArrayList<PackageParser.Package> retValue = new ArrayList<>();
7330             Set<String> collectedNames = new HashSet<>();
7331             findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
7332 
7333             retValue.remove(p);
7334 
7335             return retValue;
7336         } else {
7337             return Collections.emptyList();
7338         }
7339     }
7340 
findSharedNonSystemLibrariesRecursive(PackageParser.Package p, Collection<PackageParser.Package> collected, Set<String> collectedNames)7341     private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
7342             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7343         if (!collectedNames.contains(p.packageName)) {
7344             collectedNames.add(p.packageName);
7345             collected.add(p);
7346 
7347             if (p.usesLibraries != null) {
7348                 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames);
7349             }
7350             if (p.usesOptionalLibraries != null) {
7351                 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected,
7352                         collectedNames);
7353             }
7354         }
7355     }
7356 
findSharedNonSystemLibrariesRecursive(Collection<String> libs, Collection<PackageParser.Package> collected, Set<String> collectedNames)7357     private void findSharedNonSystemLibrariesRecursive(Collection<String> libs,
7358             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7359         for (String libName : libs) {
7360             PackageParser.Package libPkg = findSharedNonSystemLibrary(libName);
7361             if (libPkg != null) {
7362                 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
7363             }
7364         }
7365     }
7366 
findSharedNonSystemLibrary(String libName)7367     private PackageParser.Package findSharedNonSystemLibrary(String libName) {
7368         synchronized (mPackages) {
7369             PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
7370             if (lib != null && lib.apk != null) {
7371                 return mPackages.get(lib.apk);
7372             }
7373         }
7374         return null;
7375     }
7376 
shutdown()7377     public void shutdown() {
7378         mPackageUsage.writeNow(mPackages);
7379         mCompilerStats.writeNow();
7380     }
7381 
7382     @Override
dumpProfiles(String packageName)7383     public void dumpProfiles(String packageName) {
7384         PackageParser.Package pkg;
7385         synchronized (mPackages) {
7386             pkg = mPackages.get(packageName);
7387             if (pkg == null) {
7388                 throw new IllegalArgumentException("Unknown package: " + packageName);
7389             }
7390         }
7391         /* Only the shell, root, or the app user should be able to dump profiles. */
7392         int callingUid = Binder.getCallingUid();
7393         if (callingUid != Process.SHELL_UID &&
7394             callingUid != Process.ROOT_UID &&
7395             callingUid != pkg.applicationInfo.uid) {
7396             throw new SecurityException("dumpProfiles");
7397         }
7398 
7399         synchronized (mInstallLock) {
7400             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
7401             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
7402             try {
7403                 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
7404                 String gid = Integer.toString(sharedGid);
7405                 String codePaths = TextUtils.join(";", allCodePaths);
7406                 mInstaller.dumpProfiles(gid, packageName, codePaths);
7407             } catch (InstallerException e) {
7408                 Slog.w(TAG, "Failed to dump profiles", e);
7409             }
7410             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7411         }
7412     }
7413 
7414     @Override
forceDexOpt(String packageName)7415     public void forceDexOpt(String packageName) {
7416         enforceSystemOrRoot("forceDexOpt");
7417 
7418         PackageParser.Package pkg;
7419         synchronized (mPackages) {
7420             pkg = mPackages.get(packageName);
7421             if (pkg == null) {
7422                 throw new IllegalArgumentException("Unknown package: " + packageName);
7423             }
7424         }
7425 
7426         synchronized (mInstallLock) {
7427             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7428 
7429             // Whoever is calling forceDexOpt wants a fully compiled package.
7430             // Don't use profiles since that may cause compilation to be skipped.
7431             final int res = performDexOptInternalWithDependenciesLI(pkg,
7432                     false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
7433                     true /* force */);
7434 
7435             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7436             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
7437                 throw new IllegalStateException("Failed to dexopt: " + res);
7438             }
7439         }
7440     }
7441 
verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)7442     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
7443         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7444             Slog.w(TAG, "Unable to update from " + oldPkg.name
7445                     + " to " + newPkg.packageName
7446                     + ": old package not in system partition");
7447             return false;
7448         } else if (mPackages.get(oldPkg.name) != null) {
7449             Slog.w(TAG, "Unable to update from " + oldPkg.name
7450                     + " to " + newPkg.packageName
7451                     + ": old package still exists");
7452             return false;
7453         }
7454         return true;
7455     }
7456 
removeCodePathLI(File codePath)7457     void removeCodePathLI(File codePath) {
7458         if (codePath.isDirectory()) {
7459             try {
7460                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
7461             } catch (InstallerException e) {
7462                 Slog.w(TAG, "Failed to remove code path", e);
7463             }
7464         } else {
7465             codePath.delete();
7466         }
7467     }
7468 
resolveUserIds(int userId)7469     private int[] resolveUserIds(int userId) {
7470         return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
7471     }
7472 
clearAppDataLIF(PackageParser.Package pkg, int userId, int flags)7473     private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7474         if (pkg == null) {
7475             Slog.wtf(TAG, "Package was null!", new Throwable());
7476             return;
7477         }
7478         clearAppDataLeafLIF(pkg, userId, flags);
7479         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7480         for (int i = 0; i < childCount; i++) {
7481             clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7482         }
7483     }
7484 
clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags)7485     private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7486         final PackageSetting ps;
7487         synchronized (mPackages) {
7488             ps = mSettings.mPackages.get(pkg.packageName);
7489         }
7490         for (int realUserId : resolveUserIds(userId)) {
7491             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7492             try {
7493                 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7494                         ceDataInode);
7495             } catch (InstallerException e) {
7496                 Slog.w(TAG, String.valueOf(e));
7497             }
7498         }
7499     }
7500 
destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags)7501     private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7502         if (pkg == null) {
7503             Slog.wtf(TAG, "Package was null!", new Throwable());
7504             return;
7505         }
7506         destroyAppDataLeafLIF(pkg, userId, flags);
7507         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7508         for (int i = 0; i < childCount; i++) {
7509             destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7510         }
7511     }
7512 
destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags)7513     private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7514         final PackageSetting ps;
7515         synchronized (mPackages) {
7516             ps = mSettings.mPackages.get(pkg.packageName);
7517         }
7518         for (int realUserId : resolveUserIds(userId)) {
7519             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7520             try {
7521                 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7522                         ceDataInode);
7523             } catch (InstallerException e) {
7524                 Slog.w(TAG, String.valueOf(e));
7525             }
7526         }
7527     }
7528 
destroyAppProfilesLIF(PackageParser.Package pkg, int userId)7529     private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
7530         if (pkg == null) {
7531             Slog.wtf(TAG, "Package was null!", new Throwable());
7532             return;
7533         }
7534         destroyAppProfilesLeafLIF(pkg);
7535         destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */);
7536         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7537         for (int i = 0; i < childCount; i++) {
7538             destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
7539             destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId,
7540                     true /* removeBaseMarker */);
7541         }
7542     }
7543 
destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, boolean removeBaseMarker)7544     private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId,
7545             boolean removeBaseMarker) {
7546         if (pkg.isForwardLocked()) {
7547             return;
7548         }
7549 
7550         for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
7551             try {
7552                 path = PackageManagerServiceUtils.realpath(new File(path));
7553             } catch (IOException e) {
7554                 // TODO: Should we return early here ?
7555                 Slog.w(TAG, "Failed to get canonical path", e);
7556                 continue;
7557             }
7558 
7559             final String useMarker = path.replace('/', '@');
7560             for (int realUserId : resolveUserIds(userId)) {
7561                 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId);
7562                 if (removeBaseMarker) {
7563                     File foreignUseMark = new File(profileDir, useMarker);
7564                     if (foreignUseMark.exists()) {
7565                         if (!foreignUseMark.delete()) {
7566                             Slog.w(TAG, "Unable to delete foreign user mark for package: "
7567                                     + pkg.packageName);
7568                         }
7569                     }
7570                 }
7571 
7572                 File[] markers = profileDir.listFiles();
7573                 if (markers != null) {
7574                     final String searchString = "@" + pkg.packageName + "@";
7575                     // We also delete all markers that contain the package name we're
7576                     // uninstalling. These are associated with secondary dex-files belonging
7577                     // to the package. Reconstructing the path of these dex files is messy
7578                     // in general.
7579                     for (File marker : markers) {
7580                         if (marker.getName().indexOf(searchString) > 0) {
7581                             if (!marker.delete()) {
7582                                 Slog.w(TAG, "Unable to delete foreign user mark for package: "
7583                                     + pkg.packageName);
7584                             }
7585                         }
7586                     }
7587                 }
7588             }
7589         }
7590     }
7591 
destroyAppProfilesLeafLIF(PackageParser.Package pkg)7592     private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
7593         try {
7594             mInstaller.destroyAppProfiles(pkg.packageName);
7595         } catch (InstallerException e) {
7596             Slog.w(TAG, String.valueOf(e));
7597         }
7598     }
7599 
clearAppProfilesLIF(PackageParser.Package pkg, int userId)7600     private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
7601         if (pkg == null) {
7602             Slog.wtf(TAG, "Package was null!", new Throwable());
7603             return;
7604         }
7605         clearAppProfilesLeafLIF(pkg);
7606         // We don't remove the base foreign use marker when clearing profiles because
7607         // we will rename it when the app is updated. Unlike the actual profile contents,
7608         // the foreign use marker is good across installs.
7609         destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */);
7610         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7611         for (int i = 0; i < childCount; i++) {
7612             clearAppProfilesLeafLIF(pkg.childPackages.get(i));
7613         }
7614     }
7615 
clearAppProfilesLeafLIF(PackageParser.Package pkg)7616     private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
7617         try {
7618             mInstaller.clearAppProfiles(pkg.packageName);
7619         } catch (InstallerException e) {
7620             Slog.w(TAG, String.valueOf(e));
7621         }
7622     }
7623 
setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, long lastUpdateTime)7624     private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
7625             long lastUpdateTime) {
7626         // Set parent install/update time
7627         PackageSetting ps = (PackageSetting) pkg.mExtras;
7628         if (ps != null) {
7629             ps.firstInstallTime = firstInstallTime;
7630             ps.lastUpdateTime = lastUpdateTime;
7631         }
7632         // Set children install/update time
7633         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7634         for (int i = 0; i < childCount; i++) {
7635             PackageParser.Package childPkg = pkg.childPackages.get(i);
7636             ps = (PackageSetting) childPkg.mExtras;
7637             if (ps != null) {
7638                 ps.firstInstallTime = firstInstallTime;
7639                 ps.lastUpdateTime = lastUpdateTime;
7640             }
7641         }
7642     }
7643 
addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, PackageParser.Package changingLib)7644     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
7645             PackageParser.Package changingLib) {
7646         if (file.path != null) {
7647             usesLibraryFiles.add(file.path);
7648             return;
7649         }
7650         PackageParser.Package p = mPackages.get(file.apk);
7651         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
7652             // If we are doing this while in the middle of updating a library apk,
7653             // then we need to make sure to use that new apk for determining the
7654             // dependencies here.  (We haven't yet finished committing the new apk
7655             // to the package manager state.)
7656             if (p == null || p.packageName.equals(changingLib.packageName)) {
7657                 p = changingLib;
7658             }
7659         }
7660         if (p != null) {
7661             usesLibraryFiles.addAll(p.getAllCodePaths());
7662         }
7663     }
7664 
updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)7665     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
7666             PackageParser.Package changingLib) throws PackageManagerException {
7667         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
7668             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
7669             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
7670             for (int i=0; i<N; i++) {
7671                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
7672                 if (file == null) {
7673                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
7674                             "Package " + pkg.packageName + " requires unavailable shared library "
7675                             + pkg.usesLibraries.get(i) + "; failing!");
7676                 }
7677                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7678             }
7679             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
7680             for (int i=0; i<N; i++) {
7681                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
7682                 if (file == null) {
7683                     Slog.w(TAG, "Package " + pkg.packageName
7684                             + " desires unavailable shared library "
7685                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
7686                 } else {
7687                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7688                 }
7689             }
7690             N = usesLibraryFiles.size();
7691             if (N > 0) {
7692                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
7693             } else {
7694                 pkg.usesLibraryFiles = null;
7695             }
7696         }
7697     }
7698 
hasString(List<String> list, List<String> which)7699     private static boolean hasString(List<String> list, List<String> which) {
7700         if (list == null) {
7701             return false;
7702         }
7703         for (int i=list.size()-1; i>=0; i--) {
7704             for (int j=which.size()-1; j>=0; j--) {
7705                 if (which.get(j).equals(list.get(i))) {
7706                     return true;
7707                 }
7708             }
7709         }
7710         return false;
7711     }
7712 
updateAllSharedLibrariesLPw()7713     private void updateAllSharedLibrariesLPw() {
7714         for (PackageParser.Package pkg : mPackages.values()) {
7715             try {
7716                 updateSharedLibrariesLPw(pkg, null);
7717             } catch (PackageManagerException e) {
7718                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7719             }
7720         }
7721     }
7722 
updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)7723     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
7724             PackageParser.Package changingPkg) {
7725         ArrayList<PackageParser.Package> res = null;
7726         for (PackageParser.Package pkg : mPackages.values()) {
7727             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
7728                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
7729                 if (res == null) {
7730                     res = new ArrayList<PackageParser.Package>();
7731                 }
7732                 res.add(pkg);
7733                 try {
7734                     updateSharedLibrariesLPw(pkg, changingPkg);
7735                 } catch (PackageManagerException e) {
7736                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7737                 }
7738             }
7739         }
7740         return res;
7741     }
7742 
7743     /**
7744      * Derive the value of the {@code cpuAbiOverride} based on the provided
7745      * value and an optional stored value from the package settings.
7746      */
deriveAbiOverride(String abiOverride, PackageSetting settings)7747     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
7748         String cpuAbiOverride = null;
7749 
7750         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
7751             cpuAbiOverride = null;
7752         } else if (abiOverride != null) {
7753             cpuAbiOverride = abiOverride;
7754         } else if (settings != null) {
7755             cpuAbiOverride = settings.cpuAbiOverrideString;
7756         }
7757 
7758         return cpuAbiOverride;
7759     }
7760 
scanPackageTracedLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user)7761     private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
7762             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
7763                     throws PackageManagerException {
7764         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
7765         // If the package has children and this is the first dive in the function
7766         // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
7767         // whether all packages (parent and children) would be successfully scanned
7768         // before the actual scan since scanning mutates internal state and we want
7769         // to atomically install the package and its children.
7770         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7771             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
7772                 scanFlags |= SCAN_CHECK_ONLY;
7773             }
7774         } else {
7775             scanFlags &= ~SCAN_CHECK_ONLY;
7776         }
7777 
7778         final PackageParser.Package scannedPkg;
7779         try {
7780             // Scan the parent
7781             scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
7782             // Scan the children
7783             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7784             for (int i = 0; i < childCount; i++) {
7785                 PackageParser.Package childPkg = pkg.childPackages.get(i);
7786                 scanPackageLI(childPkg, policyFlags,
7787                         scanFlags, currentTime, user);
7788             }
7789         } finally {
7790             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7791         }
7792 
7793         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
7794             return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
7795         }
7796 
7797         return scannedPkg;
7798     }
7799 
scanPackageLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user)7800     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
7801             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7802         boolean success = false;
7803         try {
7804             final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
7805                     currentTime, user);
7806             success = true;
7807             return res;
7808         } finally {
7809             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
7810                 // DELETE_DATA_ON_FAILURES is only used by frozen paths
7811                 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
7812                         StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
7813                 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
7814             }
7815         }
7816     }
7817 
7818     /**
7819      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
7820      */
apkHasCode(String fileName)7821     private static boolean apkHasCode(String fileName) {
7822         StrictJarFile jarFile = null;
7823         try {
7824             jarFile = new StrictJarFile(fileName,
7825                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
7826             return jarFile.findEntry("classes.dex") != null;
7827         } catch (IOException ignore) {
7828         } finally {
7829             try {
7830                 if (jarFile != null) {
7831                     jarFile.close();
7832                 }
7833             } catch (IOException ignore) {}
7834         }
7835         return false;
7836     }
7837 
7838     /**
7839      * Enforces code policy for the package. This ensures that if an APK has
7840      * declared hasCode="true" in its manifest that the APK actually contains
7841      * code.
7842      *
7843      * @throws PackageManagerException If bytecode could not be found when it should exist
7844      */
enforceCodePolicy(PackageParser.Package pkg)7845     private static void enforceCodePolicy(PackageParser.Package pkg)
7846             throws PackageManagerException {
7847         final boolean shouldHaveCode =
7848                 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
7849         if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
7850             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
7851                     "Package " + pkg.baseCodePath + " code is missing");
7852         }
7853 
7854         if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
7855             for (int i = 0; i < pkg.splitCodePaths.length; i++) {
7856                 final boolean splitShouldHaveCode =
7857                         (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
7858                 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
7859                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
7860                             "Package " + pkg.splitCodePaths[i] + " code is missing");
7861                 }
7862             }
7863         }
7864     }
7865 
scanPackageDirtyLI(PackageParser.Package pkg, final int policyFlags, final int scanFlags, long currentTime, UserHandle user)7866     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
7867             final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
7868             throws PackageManagerException {
7869         final File scanFile = new File(pkg.codePath);
7870         if (pkg.applicationInfo.getCodePath() == null ||
7871                 pkg.applicationInfo.getResourcePath() == null) {
7872             // Bail out. The resource and code paths haven't been set.
7873             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
7874                     "Code and resource paths haven't been set correctly");
7875         }
7876 
7877         // Apply policy
7878         if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
7879             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
7880             if (pkg.applicationInfo.isDirectBootAware()) {
7881                 // we're direct boot aware; set for all components
7882                 for (PackageParser.Service s : pkg.services) {
7883                     s.info.encryptionAware = s.info.directBootAware = true;
7884                 }
7885                 for (PackageParser.Provider p : pkg.providers) {
7886                     p.info.encryptionAware = p.info.directBootAware = true;
7887                 }
7888                 for (PackageParser.Activity a : pkg.activities) {
7889                     a.info.encryptionAware = a.info.directBootAware = true;
7890                 }
7891                 for (PackageParser.Activity r : pkg.receivers) {
7892                     r.info.encryptionAware = r.info.directBootAware = true;
7893                 }
7894             }
7895         } else {
7896             // Only allow system apps to be flagged as core apps.
7897             pkg.coreApp = false;
7898             // clear flags not applicable to regular apps
7899             pkg.applicationInfo.privateFlags &=
7900                     ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
7901             pkg.applicationInfo.privateFlags &=
7902                     ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
7903         }
7904         pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
7905 
7906         if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
7907             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7908         }
7909 
7910         if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
7911             enforceCodePolicy(pkg);
7912         }
7913 
7914         if (mCustomResolverComponentName != null &&
7915                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
7916             setUpCustomResolverActivity(pkg);
7917         }
7918 
7919         if (pkg.packageName.equals("android")) {
7920             synchronized (mPackages) {
7921                 if (mAndroidApplication != null) {
7922                     Slog.w(TAG, "*************************************************");
7923                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
7924                     Slog.w(TAG, " file=" + scanFile);
7925                     Slog.w(TAG, "*************************************************");
7926                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
7927                             "Core android package being redefined.  Skipping.");
7928                 }
7929 
7930                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7931                     // Set up information for our fall-back user intent resolution activity.
7932                     mPlatformPackage = pkg;
7933                     pkg.mVersionCode = mSdkVersion;
7934                     mAndroidApplication = pkg.applicationInfo;
7935 
7936                     if (!mResolverReplaced) {
7937                         mResolveActivity.applicationInfo = mAndroidApplication;
7938                         mResolveActivity.name = ResolverActivity.class.getName();
7939                         mResolveActivity.packageName = mAndroidApplication.packageName;
7940                         mResolveActivity.processName = "system:ui";
7941                         mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
7942                         mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
7943                         mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
7944                         mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
7945                         mResolveActivity.exported = true;
7946                         mResolveActivity.enabled = true;
7947                         mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
7948                         mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
7949                                 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
7950                                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
7951                                 | ActivityInfo.CONFIG_ORIENTATION
7952                                 | ActivityInfo.CONFIG_KEYBOARD
7953                                 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
7954                         mResolveInfo.activityInfo = mResolveActivity;
7955                         mResolveInfo.priority = 0;
7956                         mResolveInfo.preferredOrder = 0;
7957                         mResolveInfo.match = 0;
7958                         mResolveComponentName = new ComponentName(
7959                                 mAndroidApplication.packageName, mResolveActivity.name);
7960                     }
7961                 }
7962             }
7963         }
7964 
7965         if (DEBUG_PACKAGE_SCANNING) {
7966             if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
7967                 Log.d(TAG, "Scanning package " + pkg.packageName);
7968         }
7969 
7970         synchronized (mPackages) {
7971             if (mPackages.containsKey(pkg.packageName)
7972                     || mSharedLibraries.containsKey(pkg.packageName)) {
7973                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
7974                         "Application package " + pkg.packageName
7975                                 + " already installed.  Skipping duplicate.");
7976             }
7977 
7978             // If we're only installing presumed-existing packages, require that the
7979             // scanned APK is both already known and at the path previously established
7980             // for it.  Previously unknown packages we pick up normally, but if we have an
7981             // a priori expectation about this package's install presence, enforce it.
7982             // With a singular exception for new system packages. When an OTA contains
7983             // a new system package, we allow the codepath to change from a system location
7984             // to the user-installed location. If we don't allow this change, any newer,
7985             // user-installed version of the application will be ignored.
7986             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
7987                 if (mExpectingBetter.containsKey(pkg.packageName)) {
7988                     logCriticalInfo(Log.WARN,
7989                             "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
7990                 } else {
7991                     PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
7992                     if (known != null) {
7993                         if (DEBUG_PACKAGE_SCANNING) {
7994                             Log.d(TAG, "Examining " + pkg.codePath
7995                                     + " and requiring known paths " + known.codePathString
7996                                     + " & " + known.resourcePathString);
7997                         }
7998                         if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
7999                                 || !pkg.applicationInfo.getResourcePath().equals(
8000                                 known.resourcePathString)) {
8001                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
8002                                     "Application package " + pkg.packageName
8003                                             + " found at " + pkg.applicationInfo.getCodePath()
8004                                             + " but expected at " + known.codePathString
8005                                             + "; ignoring.");
8006                         }
8007                     }
8008                 }
8009             }
8010         }
8011 
8012         // Initialize package source and resource directories
8013         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
8014         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
8015 
8016         SharedUserSetting suid = null;
8017         PackageSetting pkgSetting = null;
8018 
8019         if (!isSystemApp(pkg)) {
8020             // Only system apps can use these features.
8021             pkg.mOriginalPackages = null;
8022             pkg.mRealPackage = null;
8023             pkg.mAdoptPermissions = null;
8024         }
8025 
8026         // Getting the package setting may have a side-effect, so if we
8027         // are only checking if scan would succeed, stash a copy of the
8028         // old setting to restore at the end.
8029         PackageSetting nonMutatedPs = null;
8030 
8031         // writer
8032         synchronized (mPackages) {
8033             if (pkg.mSharedUserId != null) {
8034                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
8035                 if (suid == null) {
8036                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8037                             "Creating application package " + pkg.packageName
8038                             + " for shared user failed");
8039                 }
8040                 if (DEBUG_PACKAGE_SCANNING) {
8041                     if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8042                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
8043                                 + "): packages=" + suid.packages);
8044                 }
8045             }
8046 
8047             // Check if we are renaming from an original package name.
8048             PackageSetting origPackage = null;
8049             String realName = null;
8050             if (pkg.mOriginalPackages != null) {
8051                 // This package may need to be renamed to a previously
8052                 // installed name.  Let's check on that...
8053                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
8054                 if (pkg.mOriginalPackages.contains(renamed)) {
8055                     // This package had originally been installed as the
8056                     // original name, and we have already taken care of
8057                     // transitioning to the new one.  Just update the new
8058                     // one to continue using the old name.
8059                     realName = pkg.mRealPackage;
8060                     if (!pkg.packageName.equals(renamed)) {
8061                         // Callers into this function may have already taken
8062                         // care of renaming the package; only do it here if
8063                         // it is not already done.
8064                         pkg.setPackageName(renamed);
8065                     }
8066 
8067                 } else {
8068                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
8069                         if ((origPackage = mSettings.peekPackageLPr(
8070                                 pkg.mOriginalPackages.get(i))) != null) {
8071                             // We do have the package already installed under its
8072                             // original name...  should we use it?
8073                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
8074                                 // New package is not compatible with original.
8075                                 origPackage = null;
8076                                 continue;
8077                             } else if (origPackage.sharedUser != null) {
8078                                 // Make sure uid is compatible between packages.
8079                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
8080                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
8081                                             + " to " + pkg.packageName + ": old uid "
8082                                             + origPackage.sharedUser.name
8083                                             + " differs from " + pkg.mSharedUserId);
8084                                     origPackage = null;
8085                                     continue;
8086                                 }
8087                                 // TODO: Add case when shared user id is added [b/28144775]
8088                             } else {
8089                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
8090                                         + pkg.packageName + " to old name " + origPackage.name);
8091                             }
8092                             break;
8093                         }
8094                     }
8095                 }
8096             }
8097 
8098             if (mTransferedPackages.contains(pkg.packageName)) {
8099                 Slog.w(TAG, "Package " + pkg.packageName
8100                         + " was transferred to another, but its .apk remains");
8101             }
8102 
8103             // See comments in nonMutatedPs declaration
8104             if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8105                 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName);
8106                 if (foundPs != null) {
8107                     nonMutatedPs = new PackageSetting(foundPs);
8108                 }
8109             }
8110 
8111             // Just create the setting, don't add it yet. For already existing packages
8112             // the PkgSetting exists already and doesn't have to be created.
8113             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
8114                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
8115                     pkg.applicationInfo.primaryCpuAbi,
8116                     pkg.applicationInfo.secondaryCpuAbi,
8117                     pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
8118                     user, false);
8119             if (pkgSetting == null) {
8120                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8121                         "Creating application package " + pkg.packageName + " failed");
8122             }
8123 
8124             if (pkgSetting.origPackage != null) {
8125                 // If we are first transitioning from an original package,
8126                 // fix up the new package's name now.  We need to do this after
8127                 // looking up the package under its new name, so getPackageLP
8128                 // can take care of fiddling things correctly.
8129                 pkg.setPackageName(origPackage.name);
8130 
8131                 // File a report about this.
8132                 String msg = "New package " + pkgSetting.realName
8133                         + " renamed to replace old package " + pkgSetting.name;
8134                 reportSettingsProblem(Log.WARN, msg);
8135 
8136                 // Make a note of it.
8137                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8138                     mTransferedPackages.add(origPackage.name);
8139                 }
8140 
8141                 // No longer need to retain this.
8142                 pkgSetting.origPackage = null;
8143             }
8144 
8145             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
8146                 // Make a note of it.
8147                 mTransferedPackages.add(pkg.packageName);
8148             }
8149 
8150             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
8151                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
8152             }
8153 
8154             if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8155                 // Check all shared libraries and map to their actual file path.
8156                 // We only do this here for apps not on a system dir, because those
8157                 // are the only ones that can fail an install due to this.  We
8158                 // will take care of the system apps by updating all of their
8159                 // library paths after the scan is done.
8160                 updateSharedLibrariesLPw(pkg, null);
8161             }
8162 
8163             if (mFoundPolicyFile) {
8164                 SELinuxMMAC.assignSeinfoValue(pkg);
8165             }
8166 
8167             pkg.applicationInfo.uid = pkgSetting.appId;
8168             pkg.mExtras = pkgSetting;
8169             if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
8170                 if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
8171                     // We just determined the app is signed correctly, so bring
8172                     // over the latest parsed certs.
8173                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8174                 } else {
8175                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8176                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
8177                                 "Package " + pkg.packageName + " upgrade keys do not match the "
8178                                 + "previously installed version");
8179                     } else {
8180                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
8181                         String msg = "System package " + pkg.packageName
8182                             + " signature changed; retaining data.";
8183                         reportSettingsProblem(Log.WARN, msg);
8184                     }
8185                 }
8186             } else {
8187                 try {
8188                     verifySignaturesLP(pkgSetting, pkg);
8189                     // We just determined the app is signed correctly, so bring
8190                     // over the latest parsed certs.
8191                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8192                 } catch (PackageManagerException e) {
8193                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8194                         throw e;
8195                     }
8196                     // The signature has changed, but this package is in the system
8197                     // image...  let's recover!
8198                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8199                     // However...  if this package is part of a shared user, but it
8200                     // doesn't match the signature of the shared user, let's fail.
8201                     // What this means is that you can't change the signatures
8202                     // associated with an overall shared user, which doesn't seem all
8203                     // that unreasonable.
8204                     if (pkgSetting.sharedUser != null) {
8205                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8206                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
8207                             throw new PackageManagerException(
8208                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
8209                                             "Signature mismatch for shared user: "
8210                                             + pkgSetting.sharedUser);
8211                         }
8212                     }
8213                     // File a report about this.
8214                     String msg = "System package " + pkg.packageName
8215                         + " signature changed; retaining data.";
8216                     reportSettingsProblem(Log.WARN, msg);
8217                 }
8218             }
8219             // Verify that this new package doesn't have any content providers
8220             // that conflict with existing packages.  Only do this if the
8221             // package isn't already installed, since we don't want to break
8222             // things that are installed.
8223             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
8224                 final int N = pkg.providers.size();
8225                 int i;
8226                 for (i=0; i<N; i++) {
8227                     PackageParser.Provider p = pkg.providers.get(i);
8228                     if (p.info.authority != null) {
8229                         String names[] = p.info.authority.split(";");
8230                         for (int j = 0; j < names.length; j++) {
8231                             if (mProvidersByAuthority.containsKey(names[j])) {
8232                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8233                                 final String otherPackageName =
8234                                         ((other != null && other.getComponentName() != null) ?
8235                                                 other.getComponentName().getPackageName() : "?");
8236                                 throw new PackageManagerException(
8237                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
8238                                                 "Can't install because provider name " + names[j]
8239                                                 + " (in package " + pkg.applicationInfo.packageName
8240                                                 + ") is already used by " + otherPackageName);
8241                             }
8242                         }
8243                     }
8244                 }
8245             }
8246 
8247             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
8248                 // This package wants to adopt ownership of permissions from
8249                 // another package.
8250                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
8251                     final String origName = pkg.mAdoptPermissions.get(i);
8252                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
8253                     if (orig != null) {
8254                         if (verifyPackageUpdateLPr(orig, pkg)) {
8255                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
8256                                     + pkg.packageName);
8257                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
8258                         }
8259                     }
8260                 }
8261             }
8262         }
8263 
8264         final String pkgName = pkg.packageName;
8265 
8266         final long scanFileTime = getLastModifiedTime(pkg, scanFile);
8267         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
8268         pkg.applicationInfo.processName = fixProcessName(
8269                 pkg.applicationInfo.packageName,
8270                 pkg.applicationInfo.processName,
8271                 pkg.applicationInfo.uid);
8272 
8273         if (pkg != mPlatformPackage) {
8274             // Get all of our default paths setup
8275             pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
8276         }
8277 
8278         final String path = scanFile.getPath();
8279         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
8280 
8281         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
8282             derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
8283 
8284             // Some system apps still use directory structure for native libraries
8285             // in which case we might end up not detecting abi solely based on apk
8286             // structure. Try to detect abi based on directory structure.
8287             if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
8288                     pkg.applicationInfo.primaryCpuAbi == null) {
8289                 setBundledAppAbisAndRoots(pkg, pkgSetting);
8290                 setNativeLibraryPaths(pkg);
8291             }
8292 
8293         } else {
8294             if ((scanFlags & SCAN_MOVE) != 0) {
8295                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
8296                 // but we already have this packages package info in the PackageSetting. We just
8297                 // use that and derive the native library path based on the new codepath.
8298                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
8299                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
8300             }
8301 
8302             // Set native library paths again. For moves, the path will be updated based on the
8303             // ABIs we've determined above. For non-moves, the path will be updated based on the
8304             // ABIs we determined during compilation, but the path will depend on the final
8305             // package path (after the rename away from the stage path).
8306             setNativeLibraryPaths(pkg);
8307         }
8308 
8309         // This is a special case for the "system" package, where the ABI is
8310         // dictated by the zygote configuration (and init.rc). We should keep track
8311         // of this ABI so that we can deal with "normal" applications that run under
8312         // the same UID correctly.
8313         if (mPlatformPackage == pkg) {
8314             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
8315                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
8316         }
8317 
8318         // If there's a mismatch between the abi-override in the package setting
8319         // and the abiOverride specified for the install. Warn about this because we
8320         // would've already compiled the app without taking the package setting into
8321         // account.
8322         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
8323             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
8324                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
8325                         " for package " + pkg.packageName);
8326             }
8327         }
8328 
8329         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8330         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8331         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
8332 
8333         // Copy the derived override back to the parsed package, so that we can
8334         // update the package settings accordingly.
8335         pkg.cpuAbiOverride = cpuAbiOverride;
8336 
8337         if (DEBUG_ABI_SELECTION) {
8338             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
8339                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
8340                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
8341         }
8342 
8343         // Push the derived path down into PackageSettings so we know what to
8344         // clean up at uninstall time.
8345         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
8346 
8347         if (DEBUG_ABI_SELECTION) {
8348             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
8349                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
8350                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
8351         }
8352 
8353         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
8354             // We don't do this here during boot because we can do it all
8355             // at once after scanning all existing packages.
8356             //
8357             // We also do this *before* we perform dexopt on this package, so that
8358             // we can avoid redundant dexopts, and also to make sure we've got the
8359             // code and package path correct.
8360             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
8361                     pkg, true /* boot complete */);
8362         }
8363 
8364         if (mFactoryTest && pkg.requestedPermissions.contains(
8365                 android.Manifest.permission.FACTORY_TEST)) {
8366             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
8367         }
8368 
8369         ArrayList<PackageParser.Package> clientLibPkgs = null;
8370 
8371         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8372             if (nonMutatedPs != null) {
8373                 synchronized (mPackages) {
8374                     mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
8375                 }
8376             }
8377             return pkg;
8378         }
8379 
8380         // Only privileged apps and updated privileged apps can add child packages.
8381         if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
8382             if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
8383                 throw new PackageManagerException("Only privileged apps and updated "
8384                         + "privileged apps can add child packages. Ignoring package "
8385                         + pkg.packageName);
8386             }
8387             final int childCount = pkg.childPackages.size();
8388             for (int i = 0; i < childCount; i++) {
8389                 PackageParser.Package childPkg = pkg.childPackages.get(i);
8390                 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
8391                         childPkg.packageName)) {
8392                     throw new PackageManagerException("Cannot override a child package of "
8393                             + "another disabled system app. Ignoring package " + pkg.packageName);
8394                 }
8395             }
8396         }
8397 
8398         // writer
8399         synchronized (mPackages) {
8400             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8401                 // Only system apps can add new shared libraries.
8402                 if (pkg.libraryNames != null) {
8403                     for (int i=0; i<pkg.libraryNames.size(); i++) {
8404                         String name = pkg.libraryNames.get(i);
8405                         boolean allowed = false;
8406                         if (pkg.isUpdatedSystemApp()) {
8407                             // New library entries can only be added through the
8408                             // system image.  This is important to get rid of a lot
8409                             // of nasty edge cases: for example if we allowed a non-
8410                             // system update of the app to add a library, then uninstalling
8411                             // the update would make the library go away, and assumptions
8412                             // we made such as through app install filtering would now
8413                             // have allowed apps on the device which aren't compatible
8414                             // with it.  Better to just have the restriction here, be
8415                             // conservative, and create many fewer cases that can negatively
8416                             // impact the user experience.
8417                             final PackageSetting sysPs = mSettings
8418                                     .getDisabledSystemPkgLPr(pkg.packageName);
8419                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
8420                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
8421                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
8422                                         allowed = true;
8423                                         break;
8424                                     }
8425                                 }
8426                             }
8427                         } else {
8428                             allowed = true;
8429                         }
8430                         if (allowed) {
8431                             if (!mSharedLibraries.containsKey(name)) {
8432                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
8433                             } else if (!name.equals(pkg.packageName)) {
8434                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
8435                                         + name + " already exists; skipping");
8436                             }
8437                         } else {
8438                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
8439                                     + name + " that is not declared on system image; skipping");
8440                         }
8441                     }
8442                     if ((scanFlags & SCAN_BOOTING) == 0) {
8443                         // If we are not booting, we need to update any applications
8444                         // that are clients of our shared library.  If we are booting,
8445                         // this will all be done once the scan is complete.
8446                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
8447                     }
8448                 }
8449             }
8450         }
8451 
8452         if ((scanFlags & SCAN_BOOTING) != 0) {
8453             // No apps can run during boot scan, so they don't need to be frozen
8454         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
8455             // Caller asked to not kill app, so it's probably not frozen
8456         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
8457             // Caller asked us to ignore frozen check for some reason; they
8458             // probably didn't know the package name
8459         } else {
8460             // We're doing major surgery on this package, so it better be frozen
8461             // right now to keep it from launching
8462             checkPackageFrozen(pkgName);
8463         }
8464 
8465         // Also need to kill any apps that are dependent on the library.
8466         if (clientLibPkgs != null) {
8467             for (int i=0; i<clientLibPkgs.size(); i++) {
8468                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
8469                 killApplication(clientPkg.applicationInfo.packageName,
8470                         clientPkg.applicationInfo.uid, "update lib");
8471             }
8472         }
8473 
8474         // Make sure we're not adding any bogus keyset info
8475         KeySetManagerService ksms = mSettings.mKeySetManagerService;
8476         ksms.assertScannedPackageValid(pkg);
8477 
8478         // writer
8479         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
8480 
8481         boolean createIdmapFailed = false;
8482         synchronized (mPackages) {
8483             // We don't expect installation to fail beyond this point
8484 
8485             if (pkgSetting.pkg != null) {
8486                 // Note that |user| might be null during the initial boot scan. If a codePath
8487                 // for an app has changed during a boot scan, it's due to an app update that's
8488                 // part of the system partition and marker changes must be applied to all users.
8489                 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg,
8490                     (user != null) ? user : UserHandle.ALL);
8491             }
8492 
8493             // Add the new setting to mSettings
8494             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
8495             // Add the new setting to mPackages
8496             mPackages.put(pkg.applicationInfo.packageName, pkg);
8497             // Make sure we don't accidentally delete its data.
8498             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
8499             while (iter.hasNext()) {
8500                 PackageCleanItem item = iter.next();
8501                 if (pkgName.equals(item.packageName)) {
8502                     iter.remove();
8503                 }
8504             }
8505 
8506             // Take care of first install / last update times.
8507             if (currentTime != 0) {
8508                 if (pkgSetting.firstInstallTime == 0) {
8509                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
8510                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
8511                     pkgSetting.lastUpdateTime = currentTime;
8512                 }
8513             } else if (pkgSetting.firstInstallTime == 0) {
8514                 // We need *something*.  Take time time stamp of the file.
8515                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
8516             } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
8517                 if (scanFileTime != pkgSetting.timeStamp) {
8518                     // A package on the system image has changed; consider this
8519                     // to be an update.
8520                     pkgSetting.lastUpdateTime = scanFileTime;
8521                 }
8522             }
8523 
8524             // Add the package's KeySets to the global KeySetManagerService
8525             ksms.addScannedPackageLPw(pkg);
8526 
8527             int N = pkg.providers.size();
8528             StringBuilder r = null;
8529             int i;
8530             for (i=0; i<N; i++) {
8531                 PackageParser.Provider p = pkg.providers.get(i);
8532                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
8533                         p.info.processName, pkg.applicationInfo.uid);
8534                 mProviders.addProvider(p);
8535                 p.syncable = p.info.isSyncable;
8536                 if (p.info.authority != null) {
8537                     String names[] = p.info.authority.split(";");
8538                     p.info.authority = null;
8539                     for (int j = 0; j < names.length; j++) {
8540                         if (j == 1 && p.syncable) {
8541                             // We only want the first authority for a provider to possibly be
8542                             // syncable, so if we already added this provider using a different
8543                             // authority clear the syncable flag. We copy the provider before
8544                             // changing it because the mProviders object contains a reference
8545                             // to a provider that we don't want to change.
8546                             // Only do this for the second authority since the resulting provider
8547                             // object can be the same for all future authorities for this provider.
8548                             p = new PackageParser.Provider(p);
8549                             p.syncable = false;
8550                         }
8551                         if (!mProvidersByAuthority.containsKey(names[j])) {
8552                             mProvidersByAuthority.put(names[j], p);
8553                             if (p.info.authority == null) {
8554                                 p.info.authority = names[j];
8555                             } else {
8556                                 p.info.authority = p.info.authority + ";" + names[j];
8557                             }
8558                             if (DEBUG_PACKAGE_SCANNING) {
8559                                 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8560                                     Log.d(TAG, "Registered content provider: " + names[j]
8561                                             + ", className = " + p.info.name + ", isSyncable = "
8562                                             + p.info.isSyncable);
8563                             }
8564                         } else {
8565                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8566                             Slog.w(TAG, "Skipping provider name " + names[j] +
8567                                     " (in package " + pkg.applicationInfo.packageName +
8568                                     "): name already used by "
8569                                     + ((other != null && other.getComponentName() != null)
8570                                             ? other.getComponentName().getPackageName() : "?"));
8571                         }
8572                     }
8573                 }
8574                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8575                     if (r == null) {
8576                         r = new StringBuilder(256);
8577                     } else {
8578                         r.append(' ');
8579                     }
8580                     r.append(p.info.name);
8581                 }
8582             }
8583             if (r != null) {
8584                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
8585             }
8586 
8587             N = pkg.services.size();
8588             r = null;
8589             for (i=0; i<N; i++) {
8590                 PackageParser.Service s = pkg.services.get(i);
8591                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
8592                         s.info.processName, pkg.applicationInfo.uid);
8593                 mServices.addService(s);
8594                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8595                     if (r == null) {
8596                         r = new StringBuilder(256);
8597                     } else {
8598                         r.append(' ');
8599                     }
8600                     r.append(s.info.name);
8601                 }
8602             }
8603             if (r != null) {
8604                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
8605             }
8606 
8607             N = pkg.receivers.size();
8608             r = null;
8609             for (i=0; i<N; i++) {
8610                 PackageParser.Activity a = pkg.receivers.get(i);
8611                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8612                         a.info.processName, pkg.applicationInfo.uid);
8613                 mReceivers.addActivity(a, "receiver");
8614                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8615                     if (r == null) {
8616                         r = new StringBuilder(256);
8617                     } else {
8618                         r.append(' ');
8619                     }
8620                     r.append(a.info.name);
8621                 }
8622             }
8623             if (r != null) {
8624                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
8625             }
8626 
8627             N = pkg.activities.size();
8628             r = null;
8629             for (i=0; i<N; i++) {
8630                 PackageParser.Activity a = pkg.activities.get(i);
8631                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8632                         a.info.processName, pkg.applicationInfo.uid);
8633                 mActivities.addActivity(a, "activity");
8634                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8635                     if (r == null) {
8636                         r = new StringBuilder(256);
8637                     } else {
8638                         r.append(' ');
8639                     }
8640                     r.append(a.info.name);
8641                 }
8642             }
8643             if (r != null) {
8644                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
8645             }
8646 
8647             N = pkg.permissionGroups.size();
8648             r = null;
8649             for (i=0; i<N; i++) {
8650                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
8651                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
8652                 if (cur == null) {
8653                     mPermissionGroups.put(pg.info.name, pg);
8654                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8655                         if (r == null) {
8656                             r = new StringBuilder(256);
8657                         } else {
8658                             r.append(' ');
8659                         }
8660                         r.append(pg.info.name);
8661                     }
8662                 } else {
8663                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
8664                             + pg.info.packageName + " ignored: original from "
8665                             + cur.info.packageName);
8666                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8667                         if (r == null) {
8668                             r = new StringBuilder(256);
8669                         } else {
8670                             r.append(' ');
8671                         }
8672                         r.append("DUP:");
8673                         r.append(pg.info.name);
8674                     }
8675                 }
8676             }
8677             if (r != null) {
8678                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
8679             }
8680 
8681             N = pkg.permissions.size();
8682             r = null;
8683             for (i=0; i<N; i++) {
8684                 PackageParser.Permission p = pkg.permissions.get(i);
8685 
8686                 // Assume by default that we did not install this permission into the system.
8687                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
8688 
8689                 // Now that permission groups have a special meaning, we ignore permission
8690                 // groups for legacy apps to prevent unexpected behavior. In particular,
8691                 // permissions for one app being granted to someone just becase they happen
8692                 // to be in a group defined by another app (before this had no implications).
8693                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
8694                     p.group = mPermissionGroups.get(p.info.group);
8695                     // Warn for a permission in an unknown group.
8696                     if (p.info.group != null && p.group == null) {
8697                         Slog.w(TAG, "Permission " + p.info.name + " from package "
8698                                 + p.info.packageName + " in an unknown group " + p.info.group);
8699                     }
8700                 }
8701 
8702                 ArrayMap<String, BasePermission> permissionMap =
8703                         p.tree ? mSettings.mPermissionTrees
8704                                 : mSettings.mPermissions;
8705                 BasePermission bp = permissionMap.get(p.info.name);
8706 
8707                 // Allow system apps to redefine non-system permissions
8708                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
8709                     final boolean currentOwnerIsSystem = (bp.perm != null
8710                             && isSystemApp(bp.perm.owner));
8711                     if (isSystemApp(p.owner)) {
8712                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
8713                             // It's a built-in permission and no owner, take ownership now
8714                             bp.packageSetting = pkgSetting;
8715                             bp.perm = p;
8716                             bp.uid = pkg.applicationInfo.uid;
8717                             bp.sourcePackage = p.info.packageName;
8718                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8719                         } else if (!currentOwnerIsSystem) {
8720                             String msg = "New decl " + p.owner + " of permission  "
8721                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
8722                             reportSettingsProblem(Log.WARN, msg);
8723                             bp = null;
8724                         }
8725                     }
8726                 }
8727 
8728                 if (bp == null) {
8729                     bp = new BasePermission(p.info.name, p.info.packageName,
8730                             BasePermission.TYPE_NORMAL);
8731                     permissionMap.put(p.info.name, bp);
8732                 }
8733 
8734                 if (bp.perm == null) {
8735                     if (bp.sourcePackage == null
8736                             || bp.sourcePackage.equals(p.info.packageName)) {
8737                         BasePermission tree = findPermissionTreeLP(p.info.name);
8738                         if (tree == null
8739                                 || tree.sourcePackage.equals(p.info.packageName)) {
8740                             bp.packageSetting = pkgSetting;
8741                             bp.perm = p;
8742                             bp.uid = pkg.applicationInfo.uid;
8743                             bp.sourcePackage = p.info.packageName;
8744                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8745                             if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8746                                 if (r == null) {
8747                                     r = new StringBuilder(256);
8748                                 } else {
8749                                     r.append(' ');
8750                                 }
8751                                 r.append(p.info.name);
8752                             }
8753                         } else {
8754                             Slog.w(TAG, "Permission " + p.info.name + " from package "
8755                                     + p.info.packageName + " ignored: base tree "
8756                                     + tree.name + " is from package "
8757                                     + tree.sourcePackage);
8758                         }
8759                     } else {
8760                         Slog.w(TAG, "Permission " + p.info.name + " from package "
8761                                 + p.info.packageName + " ignored: original from "
8762                                 + bp.sourcePackage);
8763                     }
8764                 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8765                     if (r == null) {
8766                         r = new StringBuilder(256);
8767                     } else {
8768                         r.append(' ');
8769                     }
8770                     r.append("DUP:");
8771                     r.append(p.info.name);
8772                 }
8773                 if (bp.perm == p) {
8774                     bp.protectionLevel = p.info.protectionLevel;
8775                 }
8776             }
8777 
8778             if (r != null) {
8779                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
8780             }
8781 
8782             N = pkg.instrumentation.size();
8783             r = null;
8784             for (i=0; i<N; i++) {
8785                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8786                 a.info.packageName = pkg.applicationInfo.packageName;
8787                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
8788                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
8789                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
8790                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
8791                 a.info.dataDir = pkg.applicationInfo.dataDir;
8792                 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
8793                 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
8794 
8795                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
8796                 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
8797                 mInstrumentation.put(a.getComponentName(), a);
8798                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8799                     if (r == null) {
8800                         r = new StringBuilder(256);
8801                     } else {
8802                         r.append(' ');
8803                     }
8804                     r.append(a.info.name);
8805                 }
8806             }
8807             if (r != null) {
8808                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
8809             }
8810 
8811             if (pkg.protectedBroadcasts != null) {
8812                 N = pkg.protectedBroadcasts.size();
8813                 for (i=0; i<N; i++) {
8814                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
8815                 }
8816             }
8817 
8818             pkgSetting.setTimeStamp(scanFileTime);
8819 
8820             // Create idmap files for pairs of (packages, overlay packages).
8821             // Note: "android", ie framework-res.apk, is handled by native layers.
8822             if (pkg.mOverlayTarget != null) {
8823                 // This is an overlay package.
8824                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
8825                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
8826                         mOverlays.put(pkg.mOverlayTarget,
8827                                 new ArrayMap<String, PackageParser.Package>());
8828                     }
8829                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
8830                     map.put(pkg.packageName, pkg);
8831                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
8832                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
8833                         createIdmapFailed = true;
8834                     }
8835                 }
8836             } else if (mOverlays.containsKey(pkg.packageName) &&
8837                     !pkg.packageName.equals("android")) {
8838                 // This is a regular package, with one or more known overlay packages.
8839                 createIdmapsForPackageLI(pkg);
8840             }
8841         }
8842 
8843         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8844 
8845         if (createIdmapFailed) {
8846             throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
8847                     "scanPackageLI failed to createIdmap");
8848         }
8849         return pkg;
8850     }
8851 
maybeRenameForeignDexMarkers(PackageParser.Package existing, PackageParser.Package update, UserHandle user)8852     private void maybeRenameForeignDexMarkers(PackageParser.Package existing,
8853             PackageParser.Package update, UserHandle user) {
8854         if (existing.applicationInfo == null || update.applicationInfo == null) {
8855             // This isn't due to an app installation.
8856             return;
8857         }
8858 
8859         final File oldCodePath = new File(existing.applicationInfo.getCodePath());
8860         final File newCodePath = new File(update.applicationInfo.getCodePath());
8861 
8862         // The codePath hasn't changed, so there's nothing for us to do.
8863         if (Objects.equals(oldCodePath, newCodePath)) {
8864             return;
8865         }
8866 
8867         File canonicalNewCodePath;
8868         try {
8869             canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath));
8870         } catch (IOException e) {
8871             Slog.w(TAG, "Failed to get canonical path.", e);
8872             return;
8873         }
8874 
8875         // This is a bit of a hack. The oldCodePath doesn't exist at this point (because
8876         // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume
8877         // that the last component of the path (i.e, the name) doesn't need canonicalization
8878         // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now
8879         // but may change in the future. Hopefully this function won't exist at that point.
8880         final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(),
8881                 oldCodePath.getName());
8882 
8883         // Calculate the prefixes of the markers. These are just the paths with "/" replaced
8884         // with "@".
8885         String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@');
8886         if (!oldMarkerPrefix.endsWith("@")) {
8887             oldMarkerPrefix += "@";
8888         }
8889         String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@');
8890         if (!newMarkerPrefix.endsWith("@")) {
8891             newMarkerPrefix += "@";
8892         }
8893 
8894         List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly();
8895         List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size());
8896         for (String updatedPath : updatedPaths) {
8897             String updatedPathName = new File(updatedPath).getName();
8898             markerSuffixes.add(updatedPathName.replace('/', '@'));
8899         }
8900 
8901         for (int userId : resolveUserIds(user.getIdentifier())) {
8902             File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId);
8903 
8904             for (String markerSuffix : markerSuffixes) {
8905                 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix);
8906                 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix);
8907                 if (oldForeignUseMark.exists()) {
8908                     try {
8909                         Os.rename(oldForeignUseMark.getAbsolutePath(),
8910                                 newForeignUseMark.getAbsolutePath());
8911                     } catch (ErrnoException e) {
8912                         Slog.w(TAG, "Failed to rename foreign use marker", e);
8913                         oldForeignUseMark.delete();
8914                     }
8915                 }
8916             }
8917         }
8918     }
8919 
8920     /**
8921      * Derive the ABI of a non-system package located at {@code scanFile}. This information
8922      * is derived purely on the basis of the contents of {@code scanFile} and
8923      * {@code cpuAbiOverride}.
8924      *
8925      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
8926      */
derivePackageAbi(PackageParser.Package pkg, File scanFile, String cpuAbiOverride, boolean extractLibs)8927     private void derivePackageAbi(PackageParser.Package pkg, File scanFile,
8928                                  String cpuAbiOverride, boolean extractLibs)
8929             throws PackageManagerException {
8930         // TODO: We can probably be smarter about this stuff. For installed apps,
8931         // we can calculate this information at install time once and for all. For
8932         // system apps, we can probably assume that this information doesn't change
8933         // after the first boot scan. As things stand, we do lots of unnecessary work.
8934 
8935         // Give ourselves some initial paths; we'll come back for another
8936         // pass once we've determined ABI below.
8937         setNativeLibraryPaths(pkg);
8938 
8939         // We would never need to extract libs for forward-locked and external packages,
8940         // since the container service will do it for us. We shouldn't attempt to
8941         // extract libs from system app when it was not updated.
8942         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
8943                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
8944             extractLibs = false;
8945         }
8946 
8947         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
8948         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
8949 
8950         NativeLibraryHelper.Handle handle = null;
8951         try {
8952             handle = NativeLibraryHelper.Handle.create(pkg);
8953             // TODO(multiArch): This can be null for apps that didn't go through the
8954             // usual installation process. We can calculate it again, like we
8955             // do during install time.
8956             //
8957             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
8958             // unnecessary.
8959             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
8960 
8961             // Null out the abis so that they can be recalculated.
8962             pkg.applicationInfo.primaryCpuAbi = null;
8963             pkg.applicationInfo.secondaryCpuAbi = null;
8964             if (isMultiArch(pkg.applicationInfo)) {
8965                 // Warn if we've set an abiOverride for multi-lib packages..
8966                 // By definition, we need to copy both 32 and 64 bit libraries for
8967                 // such packages.
8968                 if (pkg.cpuAbiOverride != null
8969                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
8970                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
8971                 }
8972 
8973                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
8974                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
8975                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
8976                     if (extractLibs) {
8977                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8978                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
8979                                 useIsaSpecificSubdirs);
8980                     } else {
8981                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
8982                     }
8983                 }
8984 
8985                 maybeThrowExceptionForMultiArchCopy(
8986                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
8987 
8988                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
8989                     if (extractLibs) {
8990                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8991                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
8992                                 useIsaSpecificSubdirs);
8993                     } else {
8994                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
8995                     }
8996                 }
8997 
8998                 maybeThrowExceptionForMultiArchCopy(
8999                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
9000 
9001                 if (abi64 >= 0) {
9002                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
9003                 }
9004 
9005                 if (abi32 >= 0) {
9006                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
9007                     if (abi64 >= 0) {
9008                         if (pkg.use32bitAbi) {
9009                             pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
9010                             pkg.applicationInfo.primaryCpuAbi = abi;
9011                         } else {
9012                             pkg.applicationInfo.secondaryCpuAbi = abi;
9013                         }
9014                     } else {
9015                         pkg.applicationInfo.primaryCpuAbi = abi;
9016                     }
9017                 }
9018 
9019             } else {
9020                 String[] abiList = (cpuAbiOverride != null) ?
9021                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
9022 
9023                 // Enable gross and lame hacks for apps that are built with old
9024                 // SDK tools. We must scan their APKs for renderscript bitcode and
9025                 // not launch them if it's present. Don't bother checking on devices
9026                 // that don't have 64 bit support.
9027                 boolean needsRenderScriptOverride = false;
9028                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
9029                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
9030                     abiList = Build.SUPPORTED_32_BIT_ABIS;
9031                     needsRenderScriptOverride = true;
9032                 }
9033 
9034                 final int copyRet;
9035                 if (extractLibs) {
9036                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9037                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
9038                 } else {
9039                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
9040                 }
9041 
9042                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
9043                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
9044                             "Error unpackaging native libs for app, errorCode=" + copyRet);
9045                 }
9046 
9047                 if (copyRet >= 0) {
9048                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
9049                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
9050                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
9051                 } else if (needsRenderScriptOverride) {
9052                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
9053                 }
9054             }
9055         } catch (IOException ioe) {
9056             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
9057         } finally {
9058             IoUtils.closeQuietly(handle);
9059         }
9060 
9061         // Now that we've calculated the ABIs and determined if it's an internal app,
9062         // we will go ahead and populate the nativeLibraryPath.
9063         setNativeLibraryPaths(pkg);
9064     }
9065 
9066     /**
9067      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
9068      * i.e, so that all packages can be run inside a single process if required.
9069      *
9070      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
9071      * this function will either try and make the ABI for all packages in {@code packagesForUser}
9072      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
9073      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
9074      * updating a package that belongs to a shared user.
9075      *
9076      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
9077      * adds unnecessary complexity.
9078      */
adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage, boolean bootComplete)9079     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
9080             PackageParser.Package scannedPackage, boolean bootComplete) {
9081         String requiredInstructionSet = null;
9082         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
9083             requiredInstructionSet = VMRuntime.getInstructionSet(
9084                      scannedPackage.applicationInfo.primaryCpuAbi);
9085         }
9086 
9087         PackageSetting requirer = null;
9088         for (PackageSetting ps : packagesForUser) {
9089             // If packagesForUser contains scannedPackage, we skip it. This will happen
9090             // when scannedPackage is an update of an existing package. Without this check,
9091             // we will never be able to change the ABI of any package belonging to a shared
9092             // user, even if it's compatible with other packages.
9093             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9094                 if (ps.primaryCpuAbiString == null) {
9095                     continue;
9096                 }
9097 
9098                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
9099                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
9100                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
9101                     // this but there's not much we can do.
9102                     String errorMessage = "Instruction set mismatch, "
9103                             + ((requirer == null) ? "[caller]" : requirer)
9104                             + " requires " + requiredInstructionSet + " whereas " + ps
9105                             + " requires " + instructionSet;
9106                     Slog.w(TAG, errorMessage);
9107                 }
9108 
9109                 if (requiredInstructionSet == null) {
9110                     requiredInstructionSet = instructionSet;
9111                     requirer = ps;
9112                 }
9113             }
9114         }
9115 
9116         if (requiredInstructionSet != null) {
9117             String adjustedAbi;
9118             if (requirer != null) {
9119                 // requirer != null implies that either scannedPackage was null or that scannedPackage
9120                 // did not require an ABI, in which case we have to adjust scannedPackage to match
9121                 // the ABI of the set (which is the same as requirer's ABI)
9122                 adjustedAbi = requirer.primaryCpuAbiString;
9123                 if (scannedPackage != null) {
9124                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
9125                 }
9126             } else {
9127                 // requirer == null implies that we're updating all ABIs in the set to
9128                 // match scannedPackage.
9129                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
9130             }
9131 
9132             for (PackageSetting ps : packagesForUser) {
9133                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9134                     if (ps.primaryCpuAbiString != null) {
9135                         continue;
9136                     }
9137 
9138                     ps.primaryCpuAbiString = adjustedAbi;
9139                     if (ps.pkg != null && ps.pkg.applicationInfo != null &&
9140                             !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
9141                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
9142                         Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
9143                                 + " (requirer="
9144                                 + (requirer == null ? "null" : requirer.pkg.packageName)
9145                                 + ", scannedPackage="
9146                                 + (scannedPackage != null ? scannedPackage.packageName : "null")
9147                                 + ")");
9148                         try {
9149                             mInstaller.rmdex(ps.codePathString,
9150                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
9151                         } catch (InstallerException ignored) {
9152                         }
9153                     }
9154                 }
9155             }
9156         }
9157     }
9158 
setUpCustomResolverActivity(PackageParser.Package pkg)9159     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
9160         synchronized (mPackages) {
9161             mResolverReplaced = true;
9162             // Set up information for custom user intent resolution activity.
9163             mResolveActivity.applicationInfo = pkg.applicationInfo;
9164             mResolveActivity.name = mCustomResolverComponentName.getClassName();
9165             mResolveActivity.packageName = pkg.applicationInfo.packageName;
9166             mResolveActivity.processName = pkg.applicationInfo.packageName;
9167             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9168             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
9169                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9170             mResolveActivity.theme = 0;
9171             mResolveActivity.exported = true;
9172             mResolveActivity.enabled = true;
9173             mResolveInfo.activityInfo = mResolveActivity;
9174             mResolveInfo.priority = 0;
9175             mResolveInfo.preferredOrder = 0;
9176             mResolveInfo.match = 0;
9177             mResolveComponentName = mCustomResolverComponentName;
9178             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
9179                     mResolveComponentName);
9180         }
9181     }
9182 
setUpEphemeralInstallerActivityLP(ComponentName installerComponent)9183     private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
9184         final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
9185 
9186         // Set up information for ephemeral installer activity
9187         mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
9188         mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
9189         mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
9190         mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
9191         mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9192         mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
9193                 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9194         mEphemeralInstallerActivity.theme = 0;
9195         mEphemeralInstallerActivity.exported = true;
9196         mEphemeralInstallerActivity.enabled = true;
9197         mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
9198         mEphemeralInstallerInfo.priority = 0;
9199         mEphemeralInstallerInfo.preferredOrder = 0;
9200         mEphemeralInstallerInfo.match = 0;
9201 
9202         if (DEBUG_EPHEMERAL) {
9203             Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
9204         }
9205     }
9206 
calculateBundledApkRoot(final String codePathString)9207     private static String calculateBundledApkRoot(final String codePathString) {
9208         final File codePath = new File(codePathString);
9209         final File codeRoot;
9210         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
9211             codeRoot = Environment.getRootDirectory();
9212         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
9213             codeRoot = Environment.getOemDirectory();
9214         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
9215             codeRoot = Environment.getVendorDirectory();
9216         } else {
9217             // Unrecognized code path; take its top real segment as the apk root:
9218             // e.g. /something/app/blah.apk => /something
9219             try {
9220                 File f = codePath.getCanonicalFile();
9221                 File parent = f.getParentFile();    // non-null because codePath is a file
9222                 File tmp;
9223                 while ((tmp = parent.getParentFile()) != null) {
9224                     f = parent;
9225                     parent = tmp;
9226                 }
9227                 codeRoot = f;
9228                 Slog.w(TAG, "Unrecognized code path "
9229                         + codePath + " - using " + codeRoot);
9230             } catch (IOException e) {
9231                 // Can't canonicalize the code path -- shenanigans?
9232                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
9233                 return Environment.getRootDirectory().getPath();
9234             }
9235         }
9236         return codeRoot.getPath();
9237     }
9238 
9239     /**
9240      * Derive and set the location of native libraries for the given package,
9241      * which varies depending on where and how the package was installed.
9242      */
setNativeLibraryPaths(PackageParser.Package pkg)9243     private void setNativeLibraryPaths(PackageParser.Package pkg) {
9244         final ApplicationInfo info = pkg.applicationInfo;
9245         final String codePath = pkg.codePath;
9246         final File codeFile = new File(codePath);
9247         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
9248         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
9249 
9250         info.nativeLibraryRootDir = null;
9251         info.nativeLibraryRootRequiresIsa = false;
9252         info.nativeLibraryDir = null;
9253         info.secondaryNativeLibraryDir = null;
9254 
9255         if (isApkFile(codeFile)) {
9256             // Monolithic install
9257             if (bundledApp) {
9258                 // If "/system/lib64/apkname" exists, assume that is the per-package
9259                 // native library directory to use; otherwise use "/system/lib/apkname".
9260                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
9261                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
9262                         getPrimaryInstructionSet(info));
9263 
9264                 // This is a bundled system app so choose the path based on the ABI.
9265                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
9266                 // is just the default path.
9267                 final String apkName = deriveCodePathName(codePath);
9268                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
9269                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
9270                         apkName).getAbsolutePath();
9271 
9272                 if (info.secondaryCpuAbi != null) {
9273                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
9274                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
9275                             secondaryLibDir, apkName).getAbsolutePath();
9276                 }
9277             } else if (asecApp) {
9278                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
9279                         .getAbsolutePath();
9280             } else {
9281                 final String apkName = deriveCodePathName(codePath);
9282                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
9283                         .getAbsolutePath();
9284             }
9285 
9286             info.nativeLibraryRootRequiresIsa = false;
9287             info.nativeLibraryDir = info.nativeLibraryRootDir;
9288         } else {
9289             // Cluster install
9290             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
9291             info.nativeLibraryRootRequiresIsa = true;
9292 
9293             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
9294                     getPrimaryInstructionSet(info)).getAbsolutePath();
9295 
9296             if (info.secondaryCpuAbi != null) {
9297                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
9298                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
9299             }
9300         }
9301     }
9302 
9303     /**
9304      * Calculate the abis and roots for a bundled app. These can uniquely
9305      * be determined from the contents of the system partition, i.e whether
9306      * it contains 64 or 32 bit shared libraries etc. We do not validate any
9307      * of this information, and instead assume that the system was built
9308      * sensibly.
9309      */
setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)9310     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
9311                                            PackageSetting pkgSetting) {
9312         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
9313 
9314         // If "/system/lib64/apkname" exists, assume that is the per-package
9315         // native library directory to use; otherwise use "/system/lib/apkname".
9316         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
9317         setBundledAppAbi(pkg, apkRoot, apkName);
9318         // pkgSetting might be null during rescan following uninstall of updates
9319         // to a bundled app, so accommodate that possibility.  The settings in
9320         // that case will be established later from the parsed package.
9321         //
9322         // If the settings aren't null, sync them up with what we've just derived.
9323         // note that apkRoot isn't stored in the package settings.
9324         if (pkgSetting != null) {
9325             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9326             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9327         }
9328     }
9329 
9330     /**
9331      * Deduces the ABI of a bundled app and sets the relevant fields on the
9332      * parsed pkg object.
9333      *
9334      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
9335      *        under which system libraries are installed.
9336      * @param apkName the name of the installed package.
9337      */
setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName)9338     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
9339         final File codeFile = new File(pkg.codePath);
9340 
9341         final boolean has64BitLibs;
9342         final boolean has32BitLibs;
9343         if (isApkFile(codeFile)) {
9344             // Monolithic install
9345             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
9346             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
9347         } else {
9348             // Cluster install
9349             final File rootDir = new File(codeFile, LIB_DIR_NAME);
9350             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
9351                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
9352                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
9353                 has64BitLibs = (new File(rootDir, isa)).exists();
9354             } else {
9355                 has64BitLibs = false;
9356             }
9357             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
9358                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
9359                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
9360                 has32BitLibs = (new File(rootDir, isa)).exists();
9361             } else {
9362                 has32BitLibs = false;
9363             }
9364         }
9365 
9366         if (has64BitLibs && !has32BitLibs) {
9367             // The package has 64 bit libs, but not 32 bit libs. Its primary
9368             // ABI should be 64 bit. We can safely assume here that the bundled
9369             // native libraries correspond to the most preferred ABI in the list.
9370 
9371             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9372             pkg.applicationInfo.secondaryCpuAbi = null;
9373         } else if (has32BitLibs && !has64BitLibs) {
9374             // The package has 32 bit libs but not 64 bit libs. Its primary
9375             // ABI should be 32 bit.
9376 
9377             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9378             pkg.applicationInfo.secondaryCpuAbi = null;
9379         } else if (has32BitLibs && has64BitLibs) {
9380             // The application has both 64 and 32 bit bundled libraries. We check
9381             // here that the app declares multiArch support, and warn if it doesn't.
9382             //
9383             // We will be lenient here and record both ABIs. The primary will be the
9384             // ABI that's higher on the list, i.e, a device that's configured to prefer
9385             // 64 bit apps will see a 64 bit primary ABI,
9386 
9387             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
9388                 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
9389             }
9390 
9391             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
9392                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9393                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9394             } else {
9395                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9396                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9397             }
9398         } else {
9399             pkg.applicationInfo.primaryCpuAbi = null;
9400             pkg.applicationInfo.secondaryCpuAbi = null;
9401         }
9402     }
9403 
killApplication(String pkgName, int appId, String reason)9404     private void killApplication(String pkgName, int appId, String reason) {
9405         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
9406     }
9407 
killApplication(String pkgName, int appId, int userId, String reason)9408     private void killApplication(String pkgName, int appId, int userId, String reason) {
9409         // Request the ActivityManager to kill the process(only for existing packages)
9410         // so that we do not end up in a confused state while the user is still using the older
9411         // version of the application while the new one gets installed.
9412         final long token = Binder.clearCallingIdentity();
9413         try {
9414             IActivityManager am = ActivityManagerNative.getDefault();
9415             if (am != null) {
9416                 try {
9417                     am.killApplication(pkgName, appId, userId, reason);
9418                 } catch (RemoteException e) {
9419                 }
9420             }
9421         } finally {
9422             Binder.restoreCallingIdentity(token);
9423         }
9424     }
9425 
removePackageLI(PackageParser.Package pkg, boolean chatty)9426     private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
9427         // Remove the parent package setting
9428         PackageSetting ps = (PackageSetting) pkg.mExtras;
9429         if (ps != null) {
9430             removePackageLI(ps, chatty);
9431         }
9432         // Remove the child package setting
9433         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9434         for (int i = 0; i < childCount; i++) {
9435             PackageParser.Package childPkg = pkg.childPackages.get(i);
9436             ps = (PackageSetting) childPkg.mExtras;
9437             if (ps != null) {
9438                 removePackageLI(ps, chatty);
9439             }
9440         }
9441     }
9442 
removePackageLI(PackageSetting ps, boolean chatty)9443     void removePackageLI(PackageSetting ps, boolean chatty) {
9444         if (DEBUG_INSTALL) {
9445             if (chatty)
9446                 Log.d(TAG, "Removing package " + ps.name);
9447         }
9448 
9449         // writer
9450         synchronized (mPackages) {
9451             mPackages.remove(ps.name);
9452             final PackageParser.Package pkg = ps.pkg;
9453             if (pkg != null) {
9454                 cleanPackageDataStructuresLILPw(pkg, chatty);
9455             }
9456         }
9457     }
9458 
removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)9459     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
9460         if (DEBUG_INSTALL) {
9461             if (chatty)
9462                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
9463         }
9464 
9465         // writer
9466         synchronized (mPackages) {
9467             // Remove the parent package
9468             mPackages.remove(pkg.applicationInfo.packageName);
9469             cleanPackageDataStructuresLILPw(pkg, chatty);
9470 
9471             // Remove the child packages
9472             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9473             for (int i = 0; i < childCount; i++) {
9474                 PackageParser.Package childPkg = pkg.childPackages.get(i);
9475                 mPackages.remove(childPkg.applicationInfo.packageName);
9476                 cleanPackageDataStructuresLILPw(childPkg, chatty);
9477             }
9478         }
9479     }
9480 
cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)9481     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
9482         int N = pkg.providers.size();
9483         StringBuilder r = null;
9484         int i;
9485         for (i=0; i<N; i++) {
9486             PackageParser.Provider p = pkg.providers.get(i);
9487             mProviders.removeProvider(p);
9488             if (p.info.authority == null) {
9489 
9490                 /* There was another ContentProvider with this authority when
9491                  * this app was installed so this authority is null,
9492                  * Ignore it as we don't have to unregister the provider.
9493                  */
9494                 continue;
9495             }
9496             String names[] = p.info.authority.split(";");
9497             for (int j = 0; j < names.length; j++) {
9498                 if (mProvidersByAuthority.get(names[j]) == p) {
9499                     mProvidersByAuthority.remove(names[j]);
9500                     if (DEBUG_REMOVE) {
9501                         if (chatty)
9502                             Log.d(TAG, "Unregistered content provider: " + names[j]
9503                                     + ", className = " + p.info.name + ", isSyncable = "
9504                                     + p.info.isSyncable);
9505                     }
9506                 }
9507             }
9508             if (DEBUG_REMOVE && chatty) {
9509                 if (r == null) {
9510                     r = new StringBuilder(256);
9511                 } else {
9512                     r.append(' ');
9513                 }
9514                 r.append(p.info.name);
9515             }
9516         }
9517         if (r != null) {
9518             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
9519         }
9520 
9521         N = pkg.services.size();
9522         r = null;
9523         for (i=0; i<N; i++) {
9524             PackageParser.Service s = pkg.services.get(i);
9525             mServices.removeService(s);
9526             if (chatty) {
9527                 if (r == null) {
9528                     r = new StringBuilder(256);
9529                 } else {
9530                     r.append(' ');
9531                 }
9532                 r.append(s.info.name);
9533             }
9534         }
9535         if (r != null) {
9536             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
9537         }
9538 
9539         N = pkg.receivers.size();
9540         r = null;
9541         for (i=0; i<N; i++) {
9542             PackageParser.Activity a = pkg.receivers.get(i);
9543             mReceivers.removeActivity(a, "receiver");
9544             if (DEBUG_REMOVE && chatty) {
9545                 if (r == null) {
9546                     r = new StringBuilder(256);
9547                 } else {
9548                     r.append(' ');
9549                 }
9550                 r.append(a.info.name);
9551             }
9552         }
9553         if (r != null) {
9554             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
9555         }
9556 
9557         N = pkg.activities.size();
9558         r = null;
9559         for (i=0; i<N; i++) {
9560             PackageParser.Activity a = pkg.activities.get(i);
9561             mActivities.removeActivity(a, "activity");
9562             if (DEBUG_REMOVE && chatty) {
9563                 if (r == null) {
9564                     r = new StringBuilder(256);
9565                 } else {
9566                     r.append(' ');
9567                 }
9568                 r.append(a.info.name);
9569             }
9570         }
9571         if (r != null) {
9572             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
9573         }
9574 
9575         N = pkg.permissions.size();
9576         r = null;
9577         for (i=0; i<N; i++) {
9578             PackageParser.Permission p = pkg.permissions.get(i);
9579             BasePermission bp = mSettings.mPermissions.get(p.info.name);
9580             if (bp == null) {
9581                 bp = mSettings.mPermissionTrees.get(p.info.name);
9582             }
9583             if (bp != null && bp.perm == p) {
9584                 bp.perm = null;
9585                 if (DEBUG_REMOVE && chatty) {
9586                     if (r == null) {
9587                         r = new StringBuilder(256);
9588                     } else {
9589                         r.append(' ');
9590                     }
9591                     r.append(p.info.name);
9592                 }
9593             }
9594             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9595                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
9596                 if (appOpPkgs != null) {
9597                     appOpPkgs.remove(pkg.packageName);
9598                 }
9599             }
9600         }
9601         if (r != null) {
9602             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9603         }
9604 
9605         N = pkg.requestedPermissions.size();
9606         r = null;
9607         for (i=0; i<N; i++) {
9608             String perm = pkg.requestedPermissions.get(i);
9609             BasePermission bp = mSettings.mPermissions.get(perm);
9610             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9611                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
9612                 if (appOpPkgs != null) {
9613                     appOpPkgs.remove(pkg.packageName);
9614                     if (appOpPkgs.isEmpty()) {
9615                         mAppOpPermissionPackages.remove(perm);
9616                     }
9617                 }
9618             }
9619         }
9620         if (r != null) {
9621             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9622         }
9623 
9624         N = pkg.instrumentation.size();
9625         r = null;
9626         for (i=0; i<N; i++) {
9627             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
9628             mInstrumentation.remove(a.getComponentName());
9629             if (DEBUG_REMOVE && chatty) {
9630                 if (r == null) {
9631                     r = new StringBuilder(256);
9632                 } else {
9633                     r.append(' ');
9634                 }
9635                 r.append(a.info.name);
9636             }
9637         }
9638         if (r != null) {
9639             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
9640         }
9641 
9642         r = null;
9643         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9644             // Only system apps can hold shared libraries.
9645             if (pkg.libraryNames != null) {
9646                 for (i=0; i<pkg.libraryNames.size(); i++) {
9647                     String name = pkg.libraryNames.get(i);
9648                     SharedLibraryEntry cur = mSharedLibraries.get(name);
9649                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
9650                         mSharedLibraries.remove(name);
9651                         if (DEBUG_REMOVE && chatty) {
9652                             if (r == null) {
9653                                 r = new StringBuilder(256);
9654                             } else {
9655                                 r.append(' ');
9656                             }
9657                             r.append(name);
9658                         }
9659                     }
9660                 }
9661             }
9662         }
9663         if (r != null) {
9664             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
9665         }
9666     }
9667 
hasPermission(PackageParser.Package pkgInfo, String perm)9668     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
9669         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
9670             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
9671                 return true;
9672             }
9673         }
9674         return false;
9675     }
9676 
9677     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
9678     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
9679     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
9680 
updatePermissionsLPw(PackageParser.Package pkg, int flags)9681     private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
9682         // Update the parent permissions
9683         updatePermissionsLPw(pkg.packageName, pkg, flags);
9684         // Update the child permissions
9685         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9686         for (int i = 0; i < childCount; i++) {
9687             PackageParser.Package childPkg = pkg.childPackages.get(i);
9688             updatePermissionsLPw(childPkg.packageName, childPkg, flags);
9689         }
9690     }
9691 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)9692     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
9693             int flags) {
9694         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
9695         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
9696     }
9697 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags)9698     private void updatePermissionsLPw(String changingPkg,
9699             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
9700         // Make sure there are no dangling permission trees.
9701         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
9702         while (it.hasNext()) {
9703             final BasePermission bp = it.next();
9704             if (bp.packageSetting == null) {
9705                 // We may not yet have parsed the package, so just see if
9706                 // we still know about its settings.
9707                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9708             }
9709             if (bp.packageSetting == null) {
9710                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
9711                         + " from package " + bp.sourcePackage);
9712                 it.remove();
9713             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9714                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
9715                     Slog.i(TAG, "Removing old permission tree: " + bp.name
9716                             + " from package " + bp.sourcePackage);
9717                     flags |= UPDATE_PERMISSIONS_ALL;
9718                     it.remove();
9719                 }
9720             }
9721         }
9722 
9723         // Make sure all dynamic permissions have been assigned to a package,
9724         // and make sure there are no dangling permissions.
9725         it = mSettings.mPermissions.values().iterator();
9726         while (it.hasNext()) {
9727             final BasePermission bp = it.next();
9728             if (bp.type == BasePermission.TYPE_DYNAMIC) {
9729                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
9730                         + bp.name + " pkg=" + bp.sourcePackage
9731                         + " info=" + bp.pendingInfo);
9732                 if (bp.packageSetting == null && bp.pendingInfo != null) {
9733                     final BasePermission tree = findPermissionTreeLP(bp.name);
9734                     if (tree != null && tree.perm != null) {
9735                         bp.packageSetting = tree.packageSetting;
9736                         bp.perm = new PackageParser.Permission(tree.perm.owner,
9737                                 new PermissionInfo(bp.pendingInfo));
9738                         bp.perm.info.packageName = tree.perm.info.packageName;
9739                         bp.perm.info.name = bp.name;
9740                         bp.uid = tree.uid;
9741                     }
9742                 }
9743             }
9744             if (bp.packageSetting == null) {
9745                 // We may not yet have parsed the package, so just see if
9746                 // we still know about its settings.
9747                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9748             }
9749             if (bp.packageSetting == null) {
9750                 Slog.w(TAG, "Removing dangling permission: " + bp.name
9751                         + " from package " + bp.sourcePackage);
9752                 it.remove();
9753             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9754                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
9755                     Slog.i(TAG, "Removing old permission: " + bp.name
9756                             + " from package " + bp.sourcePackage);
9757                     flags |= UPDATE_PERMISSIONS_ALL;
9758                     it.remove();
9759                 }
9760             }
9761         }
9762 
9763         // Now update the permissions for all packages, in particular
9764         // replace the granted permissions of the system packages.
9765         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
9766             for (PackageParser.Package pkg : mPackages.values()) {
9767                 if (pkg != pkgInfo) {
9768                     // Only replace for packages on requested volume
9769                     final String volumeUuid = getVolumeUuidForPackage(pkg);
9770                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
9771                             && Objects.equals(replaceVolumeUuid, volumeUuid);
9772                     grantPermissionsLPw(pkg, replace, changingPkg);
9773                 }
9774             }
9775         }
9776 
9777         if (pkgInfo != null) {
9778             // Only replace for packages on requested volume
9779             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
9780             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
9781                     && Objects.equals(replaceVolumeUuid, volumeUuid);
9782             grantPermissionsLPw(pkgInfo, replace, changingPkg);
9783         }
9784     }
9785 
grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)9786     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
9787             String packageOfInterest) {
9788         // IMPORTANT: There are two types of permissions: install and runtime.
9789         // Install time permissions are granted when the app is installed to
9790         // all device users and users added in the future. Runtime permissions
9791         // are granted at runtime explicitly to specific users. Normal and signature
9792         // protected permissions are install time permissions. Dangerous permissions
9793         // are install permissions if the app's target SDK is Lollipop MR1 or older,
9794         // otherwise they are runtime permissions. This function does not manage
9795         // runtime permissions except for the case an app targeting Lollipop MR1
9796         // being upgraded to target a newer SDK, in which case dangerous permissions
9797         // are transformed from install time to runtime ones.
9798 
9799         final PackageSetting ps = (PackageSetting) pkg.mExtras;
9800         if (ps == null) {
9801             return;
9802         }
9803 
9804         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
9805 
9806         PermissionsState permissionsState = ps.getPermissionsState();
9807         PermissionsState origPermissions = permissionsState;
9808 
9809         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
9810 
9811         boolean runtimePermissionsRevoked = false;
9812         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
9813 
9814         boolean changedInstallPermission = false;
9815 
9816         if (replace) {
9817             ps.installPermissionsFixed = false;
9818             if (!ps.isSharedUser()) {
9819                 origPermissions = new PermissionsState(permissionsState);
9820                 permissionsState.reset();
9821             } else {
9822                 // We need to know only about runtime permission changes since the
9823                 // calling code always writes the install permissions state but
9824                 // the runtime ones are written only if changed. The only cases of
9825                 // changed runtime permissions here are promotion of an install to
9826                 // runtime and revocation of a runtime from a shared user.
9827                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
9828                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
9829                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
9830                     runtimePermissionsRevoked = true;
9831                 }
9832             }
9833         }
9834 
9835         permissionsState.setGlobalGids(mGlobalGids);
9836 
9837         final int N = pkg.requestedPermissions.size();
9838         for (int i=0; i<N; i++) {
9839             final String name = pkg.requestedPermissions.get(i);
9840             final BasePermission bp = mSettings.mPermissions.get(name);
9841 
9842             if (DEBUG_INSTALL) {
9843                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
9844             }
9845 
9846             if (bp == null || bp.packageSetting == null) {
9847                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
9848                     Slog.w(TAG, "Unknown permission " + name
9849                             + " in package " + pkg.packageName);
9850                 }
9851                 continue;
9852             }
9853 
9854             final String perm = bp.name;
9855             boolean allowedSig = false;
9856             int grant = GRANT_DENIED;
9857 
9858             // Keep track of app op permissions.
9859             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9860                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
9861                 if (pkgs == null) {
9862                     pkgs = new ArraySet<>();
9863                     mAppOpPermissionPackages.put(bp.name, pkgs);
9864                 }
9865                 pkgs.add(pkg.packageName);
9866             }
9867 
9868             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
9869             final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
9870                     >= Build.VERSION_CODES.M;
9871             switch (level) {
9872                 case PermissionInfo.PROTECTION_NORMAL: {
9873                     // For all apps normal permissions are install time ones.
9874                     grant = GRANT_INSTALL;
9875                 } break;
9876 
9877                 case PermissionInfo.PROTECTION_DANGEROUS: {
9878                     // If a permission review is required for legacy apps we represent
9879                     // their permissions as always granted runtime ones since we need
9880                     // to keep the review required permission flag per user while an
9881                     // install permission's state is shared across all users.
9882                     if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) {
9883                         // For legacy apps dangerous permissions are install time ones.
9884                         grant = GRANT_INSTALL;
9885                     } else if (origPermissions.hasInstallPermission(bp.name)) {
9886                         // For legacy apps that became modern, install becomes runtime.
9887                         grant = GRANT_UPGRADE;
9888                     } else if (mPromoteSystemApps
9889                             && isSystemApp(ps)
9890                             && mExistingSystemPackages.contains(ps.name)) {
9891                         // For legacy system apps, install becomes runtime.
9892                         // We cannot check hasInstallPermission() for system apps since those
9893                         // permissions were granted implicitly and not persisted pre-M.
9894                         grant = GRANT_UPGRADE;
9895                     } else {
9896                         // For modern apps keep runtime permissions unchanged.
9897                         grant = GRANT_RUNTIME;
9898                     }
9899                 } break;
9900 
9901                 case PermissionInfo.PROTECTION_SIGNATURE: {
9902                     // For all apps signature permissions are install time ones.
9903                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
9904                     if (allowedSig) {
9905                         grant = GRANT_INSTALL;
9906                     }
9907                 } break;
9908             }
9909 
9910             if (DEBUG_INSTALL) {
9911                 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
9912             }
9913 
9914             if (grant != GRANT_DENIED) {
9915                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
9916                     // If this is an existing, non-system package, then
9917                     // we can't add any new permissions to it.
9918                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
9919                         // Except...  if this is a permission that was added
9920                         // to the platform (note: need to only do this when
9921                         // updating the platform).
9922                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
9923                             grant = GRANT_DENIED;
9924                         }
9925                     }
9926                 }
9927 
9928                 switch (grant) {
9929                     case GRANT_INSTALL: {
9930                         // Revoke this as runtime permission to handle the case of
9931                         // a runtime permission being downgraded to an install one.
9932                         // Also in permission review mode we keep dangerous permissions
9933                         // for legacy apps
9934                         for (int userId : UserManagerService.getInstance().getUserIds()) {
9935                             if (origPermissions.getRuntimePermissionState(
9936                                     bp.name, userId) != null) {
9937                                 // Revoke the runtime permission and clear the flags.
9938                                 origPermissions.revokeRuntimePermission(bp, userId);
9939                                 origPermissions.updatePermissionFlags(bp, userId,
9940                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
9941                                 // If we revoked a permission permission, we have to write.
9942                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9943                                         changedRuntimePermissionUserIds, userId);
9944                             }
9945                         }
9946                         // Grant an install permission.
9947                         if (permissionsState.grantInstallPermission(bp) !=
9948                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
9949                             changedInstallPermission = true;
9950                         }
9951                     } break;
9952 
9953                     case GRANT_RUNTIME: {
9954                         // Grant previously granted runtime permissions.
9955                         for (int userId : UserManagerService.getInstance().getUserIds()) {
9956                             PermissionState permissionState = origPermissions
9957                                     .getRuntimePermissionState(bp.name, userId);
9958                             int flags = permissionState != null
9959                                     ? permissionState.getFlags() : 0;
9960                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
9961                                 if (permissionsState.grantRuntimePermission(bp, userId) ==
9962                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
9963                                     // If we cannot put the permission as it was, we have to write.
9964                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9965                                             changedRuntimePermissionUserIds, userId);
9966                                 }
9967                                 // If the app supports runtime permissions no need for a review.
9968                                 if (Build.PERMISSIONS_REVIEW_REQUIRED
9969                                         && appSupportsRuntimePermissions
9970                                         && (flags & PackageManager
9971                                                 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
9972                                     flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
9973                                     // Since we changed the flags, we have to write.
9974                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9975                                             changedRuntimePermissionUserIds, userId);
9976                                 }
9977                             } else if (Build.PERMISSIONS_REVIEW_REQUIRED
9978                                     && !appSupportsRuntimePermissions) {
9979                                 // For legacy apps that need a permission review, every new
9980                                 // runtime permission is granted but it is pending a review.
9981                                 // We also need to review only platform defined runtime
9982                                 // permissions as these are the only ones the platform knows
9983                                 // how to disable the API to simulate revocation as legacy
9984                                 // apps don't expect to run with revoked permissions.
9985                                 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
9986                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
9987                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
9988                                         // We changed the flags, hence have to write.
9989                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9990                                                 changedRuntimePermissionUserIds, userId);
9991                                     }
9992                                 }
9993                                 if (permissionsState.grantRuntimePermission(bp, userId)
9994                                         != PermissionsState.PERMISSION_OPERATION_FAILURE) {
9995                                     // We changed the permission, hence have to write.
9996                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9997                                             changedRuntimePermissionUserIds, userId);
9998                                 }
9999                             }
10000                             // Propagate the permission flags.
10001                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
10002                         }
10003                     } break;
10004 
10005                     case GRANT_UPGRADE: {
10006                         // Grant runtime permissions for a previously held install permission.
10007                         PermissionState permissionState = origPermissions
10008                                 .getInstallPermissionState(bp.name);
10009                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
10010 
10011                         if (origPermissions.revokeInstallPermission(bp)
10012                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
10013                             // We will be transferring the permission flags, so clear them.
10014                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
10015                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
10016                             changedInstallPermission = true;
10017                         }
10018 
10019                         // If the permission is not to be promoted to runtime we ignore it and
10020                         // also its other flags as they are not applicable to install permissions.
10021                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
10022                             for (int userId : currentUserIds) {
10023                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
10024                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
10025                                     // Transfer the permission flags.
10026                                     permissionsState.updatePermissionFlags(bp, userId,
10027                                             flags, flags);
10028                                     // If we granted the permission, we have to write.
10029                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10030                                             changedRuntimePermissionUserIds, userId);
10031                                 }
10032                             }
10033                         }
10034                     } break;
10035 
10036                     default: {
10037                         if (packageOfInterest == null
10038                                 || packageOfInterest.equals(pkg.packageName)) {
10039                             Slog.w(TAG, "Not granting permission " + perm
10040                                     + " to package " + pkg.packageName
10041                                     + " because it was previously installed without");
10042                         }
10043                     } break;
10044                 }
10045             } else {
10046                 if (permissionsState.revokeInstallPermission(bp) !=
10047                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
10048                     // Also drop the permission flags.
10049                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
10050                             PackageManager.MASK_PERMISSION_FLAGS, 0);
10051                     changedInstallPermission = true;
10052                     Slog.i(TAG, "Un-granting permission " + perm
10053                             + " from package " + pkg.packageName
10054                             + " (protectionLevel=" + bp.protectionLevel
10055                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10056                             + ")");
10057                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
10058                     // Don't print warning for app op permissions, since it is fine for them
10059                     // not to be granted, there is a UI for the user to decide.
10060                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
10061                         Slog.w(TAG, "Not granting permission " + perm
10062                                 + " to package " + pkg.packageName
10063                                 + " (protectionLevel=" + bp.protectionLevel
10064                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10065                                 + ")");
10066                     }
10067                 }
10068             }
10069         }
10070 
10071         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
10072                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
10073             // This is the first that we have heard about this package, so the
10074             // permissions we have now selected are fixed until explicitly
10075             // changed.
10076             ps.installPermissionsFixed = true;
10077         }
10078 
10079         // Persist the runtime permissions state for users with changes. If permissions
10080         // were revoked because no app in the shared user declares them we have to
10081         // write synchronously to avoid losing runtime permissions state.
10082         for (int userId : changedRuntimePermissionUserIds) {
10083             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
10084         }
10085 
10086         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10087     }
10088 
isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)10089     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
10090         boolean allowed = false;
10091         final int NP = PackageParser.NEW_PERMISSIONS.length;
10092         for (int ip=0; ip<NP; ip++) {
10093             final PackageParser.NewPermissionInfo npi
10094                     = PackageParser.NEW_PERMISSIONS[ip];
10095             if (npi.name.equals(perm)
10096                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
10097                 allowed = true;
10098                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
10099                         + pkg.packageName);
10100                 break;
10101             }
10102         }
10103         return allowed;
10104     }
10105 
grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions)10106     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
10107             BasePermission bp, PermissionsState origPermissions) {
10108         boolean allowed;
10109         allowed = (compareSignatures(
10110                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
10111                         == PackageManager.SIGNATURE_MATCH)
10112                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
10113                         == PackageManager.SIGNATURE_MATCH);
10114         if (!allowed && (bp.protectionLevel
10115                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
10116             if (isSystemApp(pkg)) {
10117                 // For updated system applications, a system permission
10118                 // is granted only if it had been defined by the original application.
10119                 if (pkg.isUpdatedSystemApp()) {
10120                     final PackageSetting sysPs = mSettings
10121                             .getDisabledSystemPkgLPr(pkg.packageName);
10122                     if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
10123                         // If the original was granted this permission, we take
10124                         // that grant decision as read and propagate it to the
10125                         // update.
10126                         if (sysPs.isPrivileged()) {
10127                             allowed = true;
10128                         }
10129                     } else {
10130                         // The system apk may have been updated with an older
10131                         // version of the one on the data partition, but which
10132                         // granted a new system permission that it didn't have
10133                         // before.  In this case we do want to allow the app to
10134                         // now get the new permission if the ancestral apk is
10135                         // privileged to get it.
10136                         if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
10137                             for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
10138                                 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
10139                                     allowed = true;
10140                                     break;
10141                                 }
10142                             }
10143                         }
10144                         // Also if a privileged parent package on the system image or any of
10145                         // its children requested a privileged permission, the updated child
10146                         // packages can also get the permission.
10147                         if (pkg.parentPackage != null) {
10148                             final PackageSetting disabledSysParentPs = mSettings
10149                                     .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
10150                             if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
10151                                     && disabledSysParentPs.isPrivileged()) {
10152                                 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
10153                                     allowed = true;
10154                                 } else if (disabledSysParentPs.pkg.childPackages != null) {
10155                                     final int count = disabledSysParentPs.pkg.childPackages.size();
10156                                     for (int i = 0; i < count; i++) {
10157                                         PackageParser.Package disabledSysChildPkg =
10158                                                 disabledSysParentPs.pkg.childPackages.get(i);
10159                                         if (isPackageRequestingPermission(disabledSysChildPkg,
10160                                                 perm)) {
10161                                             allowed = true;
10162                                             break;
10163                                         }
10164                                     }
10165                                 }
10166                             }
10167                         }
10168                     }
10169                 } else {
10170                     allowed = isPrivilegedApp(pkg);
10171                 }
10172             }
10173         }
10174         if (!allowed) {
10175             if (!allowed && (bp.protectionLevel
10176                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
10177                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
10178                 // If this was a previously normal/dangerous permission that got moved
10179                 // to a system permission as part of the runtime permission redesign, then
10180                 // we still want to blindly grant it to old apps.
10181                 allowed = true;
10182             }
10183             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
10184                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
10185                 // If this permission is to be granted to the system installer and
10186                 // this app is an installer, then it gets the permission.
10187                 allowed = true;
10188             }
10189             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
10190                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
10191                 // If this permission is to be granted to the system verifier and
10192                 // this app is a verifier, then it gets the permission.
10193                 allowed = true;
10194             }
10195             if (!allowed && (bp.protectionLevel
10196                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
10197                     && isSystemApp(pkg)) {
10198                 // Any pre-installed system app is allowed to get this permission.
10199                 allowed = true;
10200             }
10201             if (!allowed && (bp.protectionLevel
10202                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
10203                 // For development permissions, a development permission
10204                 // is granted only if it was already granted.
10205                 allowed = origPermissions.hasInstallPermission(perm);
10206             }
10207             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
10208                     && pkg.packageName.equals(mSetupWizardPackage)) {
10209                 // If this permission is to be granted to the system setup wizard and
10210                 // this app is a setup wizard, then it gets the permission.
10211                 allowed = true;
10212             }
10213         }
10214         return allowed;
10215     }
10216 
isPackageRequestingPermission(PackageParser.Package pkg, String permission)10217     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
10218         final int permCount = pkg.requestedPermissions.size();
10219         for (int j = 0; j < permCount; j++) {
10220             String requestedPermission = pkg.requestedPermissions.get(j);
10221             if (permission.equals(requestedPermission)) {
10222                 return true;
10223             }
10224         }
10225         return false;
10226     }
10227 
10228     final class ActivityIntentResolver
10229             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)10230         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10231                 boolean defaultOnly, int userId) {
10232             if (!sUserManager.exists(userId)) return null;
10233             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10234             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10235         }
10236 
queryIntent(Intent intent, String resolvedType, int flags, int userId)10237         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10238                 int userId) {
10239             if (!sUserManager.exists(userId)) return null;
10240             mFlags = flags;
10241             return super.queryIntent(intent, resolvedType,
10242                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10243         }
10244 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)10245         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10246                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
10247             if (!sUserManager.exists(userId)) return null;
10248             if (packageActivities == null) {
10249                 return null;
10250             }
10251             mFlags = flags;
10252             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
10253             final int N = packageActivities.size();
10254             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
10255                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
10256 
10257             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
10258             for (int i = 0; i < N; ++i) {
10259                 intentFilters = packageActivities.get(i).intents;
10260                 if (intentFilters != null && intentFilters.size() > 0) {
10261                     PackageParser.ActivityIntentInfo[] array =
10262                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
10263                     intentFilters.toArray(array);
10264                     listCut.add(array);
10265                 }
10266             }
10267             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
10268         }
10269 
10270         /**
10271          * Finds a privileged activity that matches the specified activity names.
10272          */
findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo)10273         private PackageParser.Activity findMatchingActivity(
10274                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
10275             for (PackageParser.Activity sysActivity : activityList) {
10276                 if (sysActivity.info.name.equals(activityInfo.name)) {
10277                     return sysActivity;
10278                 }
10279                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
10280                     return sysActivity;
10281                 }
10282                 if (sysActivity.info.targetActivity != null) {
10283                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
10284                         return sysActivity;
10285                     }
10286                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
10287                         return sysActivity;
10288                     }
10289                 }
10290             }
10291             return null;
10292         }
10293 
10294         public class IterGenerator<E> {
generate(ActivityIntentInfo info)10295             public Iterator<E> generate(ActivityIntentInfo info) {
10296                 return null;
10297             }
10298         }
10299 
10300         public class ActionIterGenerator extends IterGenerator<String> {
10301             @Override
generate(ActivityIntentInfo info)10302             public Iterator<String> generate(ActivityIntentInfo info) {
10303                 return info.actionsIterator();
10304             }
10305         }
10306 
10307         public class CategoriesIterGenerator extends IterGenerator<String> {
10308             @Override
generate(ActivityIntentInfo info)10309             public Iterator<String> generate(ActivityIntentInfo info) {
10310                 return info.categoriesIterator();
10311             }
10312         }
10313 
10314         public class SchemesIterGenerator extends IterGenerator<String> {
10315             @Override
generate(ActivityIntentInfo info)10316             public Iterator<String> generate(ActivityIntentInfo info) {
10317                 return info.schemesIterator();
10318             }
10319         }
10320 
10321         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
10322             @Override
generate(ActivityIntentInfo info)10323             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
10324                 return info.authoritiesIterator();
10325             }
10326         }
10327 
10328         /**
10329          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
10330          * MODIFIED. Do not pass in a list that should not be changed.
10331          */
getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator)10332         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
10333                 IterGenerator<T> generator, Iterator<T> searchIterator) {
10334             // loop through the set of actions; every one must be found in the intent filter
10335             while (searchIterator.hasNext()) {
10336                 // we must have at least one filter in the list to consider a match
10337                 if (intentList.size() == 0) {
10338                     break;
10339                 }
10340 
10341                 final T searchAction = searchIterator.next();
10342 
10343                 // loop through the set of intent filters
10344                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
10345                 while (intentIter.hasNext()) {
10346                     final ActivityIntentInfo intentInfo = intentIter.next();
10347                     boolean selectionFound = false;
10348 
10349                     // loop through the intent filter's selection criteria; at least one
10350                     // of them must match the searched criteria
10351                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
10352                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
10353                         final T intentSelection = intentSelectionIter.next();
10354                         if (intentSelection != null && intentSelection.equals(searchAction)) {
10355                             selectionFound = true;
10356                             break;
10357                         }
10358                     }
10359 
10360                     // the selection criteria wasn't found in this filter's set; this filter
10361                     // is not a potential match
10362                     if (!selectionFound) {
10363                         intentIter.remove();
10364                     }
10365                 }
10366             }
10367         }
10368 
isProtectedAction(ActivityIntentInfo filter)10369         private boolean isProtectedAction(ActivityIntentInfo filter) {
10370             final Iterator<String> actionsIter = filter.actionsIterator();
10371             while (actionsIter != null && actionsIter.hasNext()) {
10372                 final String filterAction = actionsIter.next();
10373                 if (PROTECTED_ACTIONS.contains(filterAction)) {
10374                     return true;
10375                 }
10376             }
10377             return false;
10378         }
10379 
10380         /**
10381          * Adjusts the priority of the given intent filter according to policy.
10382          * <p>
10383          * <ul>
10384          * <li>The priority for non privileged applications is capped to '0'</li>
10385          * <li>The priority for protected actions on privileged applications is capped to '0'</li>
10386          * <li>The priority for unbundled updates to privileged applications is capped to the
10387          *      priority defined on the system partition</li>
10388          * </ul>
10389          * <p>
10390          * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
10391          * allowed to obtain any priority on any action.
10392          */
adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent)10393         private void adjustPriority(
10394                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
10395             // nothing to do; priority is fine as-is
10396             if (intent.getPriority() <= 0) {
10397                 return;
10398             }
10399 
10400             final ActivityInfo activityInfo = intent.activity.info;
10401             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
10402 
10403             final boolean privilegedApp =
10404                     ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
10405             if (!privilegedApp) {
10406                 // non-privileged applications can never define a priority >0
10407                 Slog.w(TAG, "Non-privileged app; cap priority to 0;"
10408                         + " package: " + applicationInfo.packageName
10409                         + " activity: " + intent.activity.className
10410                         + " origPrio: " + intent.getPriority());
10411                 intent.setPriority(0);
10412                 return;
10413             }
10414 
10415             if (systemActivities == null) {
10416                 // the system package is not disabled; we're parsing the system partition
10417                 if (isProtectedAction(intent)) {
10418                     if (mDeferProtectedFilters) {
10419                         // We can't deal with these just yet. No component should ever obtain a
10420                         // >0 priority for a protected actions, with ONE exception -- the setup
10421                         // wizard. The setup wizard, however, cannot be known until we're able to
10422                         // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
10423                         // until all intent filters have been processed. Chicken, meet egg.
10424                         // Let the filter temporarily have a high priority and rectify the
10425                         // priorities after all system packages have been scanned.
10426                         mProtectedFilters.add(intent);
10427                         if (DEBUG_FILTERS) {
10428                             Slog.i(TAG, "Protected action; save for later;"
10429                                     + " package: " + applicationInfo.packageName
10430                                     + " activity: " + intent.activity.className
10431                                     + " origPrio: " + intent.getPriority());
10432                         }
10433                         return;
10434                     } else {
10435                         if (DEBUG_FILTERS && mSetupWizardPackage == null) {
10436                             Slog.i(TAG, "No setup wizard;"
10437                                 + " All protected intents capped to priority 0");
10438                         }
10439                         if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
10440                             if (DEBUG_FILTERS) {
10441                                 Slog.i(TAG, "Found setup wizard;"
10442                                     + " allow priority " + intent.getPriority() + ";"
10443                                     + " package: " + intent.activity.info.packageName
10444                                     + " activity: " + intent.activity.className
10445                                     + " priority: " + intent.getPriority());
10446                             }
10447                             // setup wizard gets whatever it wants
10448                             return;
10449                         }
10450                         Slog.w(TAG, "Protected action; cap priority to 0;"
10451                                 + " package: " + intent.activity.info.packageName
10452                                 + " activity: " + intent.activity.className
10453                                 + " origPrio: " + intent.getPriority());
10454                         intent.setPriority(0);
10455                         return;
10456                     }
10457                 }
10458                 // privileged apps on the system image get whatever priority they request
10459                 return;
10460             }
10461 
10462             // privileged app unbundled update ... try to find the same activity
10463             final PackageParser.Activity foundActivity =
10464                     findMatchingActivity(systemActivities, activityInfo);
10465             if (foundActivity == null) {
10466                 // this is a new activity; it cannot obtain >0 priority
10467                 if (DEBUG_FILTERS) {
10468                     Slog.i(TAG, "New activity; cap priority to 0;"
10469                             + " package: " + applicationInfo.packageName
10470                             + " activity: " + intent.activity.className
10471                             + " origPrio: " + intent.getPriority());
10472                 }
10473                 intent.setPriority(0);
10474                 return;
10475             }
10476 
10477             // found activity, now check for filter equivalence
10478 
10479             // a shallow copy is enough; we modify the list, not its contents
10480             final List<ActivityIntentInfo> intentListCopy =
10481                     new ArrayList<>(foundActivity.intents);
10482             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
10483 
10484             // find matching action subsets
10485             final Iterator<String> actionsIterator = intent.actionsIterator();
10486             if (actionsIterator != null) {
10487                 getIntentListSubset(
10488                         intentListCopy, new ActionIterGenerator(), actionsIterator);
10489                 if (intentListCopy.size() == 0) {
10490                     // no more intents to match; we're not equivalent
10491                     if (DEBUG_FILTERS) {
10492                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
10493                                 + " package: " + applicationInfo.packageName
10494                                 + " activity: " + intent.activity.className
10495                                 + " origPrio: " + intent.getPriority());
10496                     }
10497                     intent.setPriority(0);
10498                     return;
10499                 }
10500             }
10501 
10502             // find matching category subsets
10503             final Iterator<String> categoriesIterator = intent.categoriesIterator();
10504             if (categoriesIterator != null) {
10505                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
10506                         categoriesIterator);
10507                 if (intentListCopy.size() == 0) {
10508                     // no more intents to match; we're not equivalent
10509                     if (DEBUG_FILTERS) {
10510                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
10511                                 + " package: " + applicationInfo.packageName
10512                                 + " activity: " + intent.activity.className
10513                                 + " origPrio: " + intent.getPriority());
10514                     }
10515                     intent.setPriority(0);
10516                     return;
10517                 }
10518             }
10519 
10520             // find matching schemes subsets
10521             final Iterator<String> schemesIterator = intent.schemesIterator();
10522             if (schemesIterator != null) {
10523                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
10524                         schemesIterator);
10525                 if (intentListCopy.size() == 0) {
10526                     // no more intents to match; we're not equivalent
10527                     if (DEBUG_FILTERS) {
10528                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
10529                                 + " package: " + applicationInfo.packageName
10530                                 + " activity: " + intent.activity.className
10531                                 + " origPrio: " + intent.getPriority());
10532                     }
10533                     intent.setPriority(0);
10534                     return;
10535                 }
10536             }
10537 
10538             // find matching authorities subsets
10539             final Iterator<IntentFilter.AuthorityEntry>
10540                     authoritiesIterator = intent.authoritiesIterator();
10541             if (authoritiesIterator != null) {
10542                 getIntentListSubset(intentListCopy,
10543                         new AuthoritiesIterGenerator(),
10544                         authoritiesIterator);
10545                 if (intentListCopy.size() == 0) {
10546                     // no more intents to match; we're not equivalent
10547                     if (DEBUG_FILTERS) {
10548                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
10549                                 + " package: " + applicationInfo.packageName
10550                                 + " activity: " + intent.activity.className
10551                                 + " origPrio: " + intent.getPriority());
10552                     }
10553                     intent.setPriority(0);
10554                     return;
10555                 }
10556             }
10557 
10558             // we found matching filter(s); app gets the max priority of all intents
10559             int cappedPriority = 0;
10560             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
10561                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
10562             }
10563             if (intent.getPriority() > cappedPriority) {
10564                 if (DEBUG_FILTERS) {
10565                     Slog.i(TAG, "Found matching filter(s);"
10566                             + " cap priority to " + cappedPriority + ";"
10567                             + " package: " + applicationInfo.packageName
10568                             + " activity: " + intent.activity.className
10569                             + " origPrio: " + intent.getPriority());
10570                 }
10571                 intent.setPriority(cappedPriority);
10572                 return;
10573             }
10574             // all this for nothing; the requested priority was <= what was on the system
10575         }
10576 
addActivity(PackageParser.Activity a, String type)10577         public final void addActivity(PackageParser.Activity a, String type) {
10578             mActivities.put(a.getComponentName(), a);
10579             if (DEBUG_SHOW_INFO)
10580                 Log.v(
10581                 TAG, "  " + type + " " +
10582                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
10583             if (DEBUG_SHOW_INFO)
10584                 Log.v(TAG, "    Class=" + a.info.name);
10585             final int NI = a.intents.size();
10586             for (int j=0; j<NI; j++) {
10587                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10588                 if ("activity".equals(type)) {
10589                     final PackageSetting ps =
10590                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
10591                     final List<PackageParser.Activity> systemActivities =
10592                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
10593                     adjustPriority(systemActivities, intent);
10594                 }
10595                 if (DEBUG_SHOW_INFO) {
10596                     Log.v(TAG, "    IntentFilter:");
10597                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10598                 }
10599                 if (!intent.debugCheck()) {
10600                     Log.w(TAG, "==> For Activity " + a.info.name);
10601                 }
10602                 addFilter(intent);
10603             }
10604         }
10605 
removeActivity(PackageParser.Activity a, String type)10606         public final void removeActivity(PackageParser.Activity a, String type) {
10607             mActivities.remove(a.getComponentName());
10608             if (DEBUG_SHOW_INFO) {
10609                 Log.v(TAG, "  " + type + " "
10610                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
10611                                 : a.info.name) + ":");
10612                 Log.v(TAG, "    Class=" + a.info.name);
10613             }
10614             final int NI = a.intents.size();
10615             for (int j=0; j<NI; j++) {
10616                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10617                 if (DEBUG_SHOW_INFO) {
10618                     Log.v(TAG, "    IntentFilter:");
10619                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10620                 }
10621                 removeFilter(intent);
10622             }
10623         }
10624 
10625         @Override
allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)10626         protected boolean allowFilterResult(
10627                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
10628             ActivityInfo filterAi = filter.activity.info;
10629             for (int i=dest.size()-1; i>=0; i--) {
10630                 ActivityInfo destAi = dest.get(i).activityInfo;
10631                 if (destAi.name == filterAi.name
10632                         && destAi.packageName == filterAi.packageName) {
10633                     return false;
10634                 }
10635             }
10636             return true;
10637         }
10638 
10639         @Override
newArray(int size)10640         protected ActivityIntentInfo[] newArray(int size) {
10641             return new ActivityIntentInfo[size];
10642         }
10643 
10644         @Override
isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)10645         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
10646             if (!sUserManager.exists(userId)) return true;
10647             PackageParser.Package p = filter.activity.owner;
10648             if (p != null) {
10649                 PackageSetting ps = (PackageSetting)p.mExtras;
10650                 if (ps != null) {
10651                     // System apps are never considered stopped for purposes of
10652                     // filtering, because there may be no way for the user to
10653                     // actually re-launch them.
10654                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
10655                             && ps.getStopped(userId);
10656                 }
10657             }
10658             return false;
10659         }
10660 
10661         @Override
isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)10662         protected boolean isPackageForFilter(String packageName,
10663                 PackageParser.ActivityIntentInfo info) {
10664             return packageName.equals(info.activity.owner.packageName);
10665         }
10666 
10667         @Override
newResult(PackageParser.ActivityIntentInfo info, int match, int userId)10668         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
10669                 int match, int userId) {
10670             if (!sUserManager.exists(userId)) return null;
10671             if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
10672                 return null;
10673             }
10674             final PackageParser.Activity activity = info.activity;
10675             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
10676             if (ps == null) {
10677                 return null;
10678             }
10679             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
10680                     ps.readUserState(userId), userId);
10681             if (ai == null) {
10682                 return null;
10683             }
10684             final ResolveInfo res = new ResolveInfo();
10685             res.activityInfo = ai;
10686             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
10687                 res.filter = info;
10688             }
10689             if (info != null) {
10690                 res.handleAllWebDataURI = info.handleAllWebDataURI();
10691             }
10692             res.priority = info.getPriority();
10693             res.preferredOrder = activity.owner.mPreferredOrder;
10694             //System.out.println("Result: " + res.activityInfo.className +
10695             //                   " = " + res.priority);
10696             res.match = match;
10697             res.isDefault = info.hasDefault;
10698             res.labelRes = info.labelRes;
10699             res.nonLocalizedLabel = info.nonLocalizedLabel;
10700             if (userNeedsBadging(userId)) {
10701                 res.noResourceId = true;
10702             } else {
10703                 res.icon = info.icon;
10704             }
10705             res.iconResourceId = info.icon;
10706             res.system = res.activityInfo.applicationInfo.isSystemApp();
10707             return res;
10708         }
10709 
10710         @Override
sortResults(List<ResolveInfo> results)10711         protected void sortResults(List<ResolveInfo> results) {
10712             Collections.sort(results, mResolvePrioritySorter);
10713         }
10714 
10715         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)10716         protected void dumpFilter(PrintWriter out, String prefix,
10717                 PackageParser.ActivityIntentInfo filter) {
10718             out.print(prefix); out.print(
10719                     Integer.toHexString(System.identityHashCode(filter.activity)));
10720                     out.print(' ');
10721                     filter.activity.printComponentShortName(out);
10722                     out.print(" filter ");
10723                     out.println(Integer.toHexString(System.identityHashCode(filter)));
10724         }
10725 
10726         @Override
filterToLabel(PackageParser.ActivityIntentInfo filter)10727         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
10728             return filter.activity;
10729         }
10730 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)10731         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
10732             PackageParser.Activity activity = (PackageParser.Activity)label;
10733             out.print(prefix); out.print(
10734                     Integer.toHexString(System.identityHashCode(activity)));
10735                     out.print(' ');
10736                     activity.printComponentShortName(out);
10737             if (count > 1) {
10738                 out.print(" ("); out.print(count); out.print(" filters)");
10739             }
10740             out.println();
10741         }
10742 
10743         // Keys are String (activity class name), values are Activity.
10744         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
10745                 = new ArrayMap<ComponentName, PackageParser.Activity>();
10746         private int mFlags;
10747     }
10748 
10749     private final class ServiceIntentResolver
10750             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)10751         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10752                 boolean defaultOnly, int userId) {
10753             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10754             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10755         }
10756 
queryIntent(Intent intent, String resolvedType, int flags, int userId)10757         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10758                 int userId) {
10759             if (!sUserManager.exists(userId)) return null;
10760             mFlags = flags;
10761             return super.queryIntent(intent, resolvedType,
10762                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10763         }
10764 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)10765         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10766                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
10767             if (!sUserManager.exists(userId)) return null;
10768             if (packageServices == null) {
10769                 return null;
10770             }
10771             mFlags = flags;
10772             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
10773             final int N = packageServices.size();
10774             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
10775                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
10776 
10777             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
10778             for (int i = 0; i < N; ++i) {
10779                 intentFilters = packageServices.get(i).intents;
10780                 if (intentFilters != null && intentFilters.size() > 0) {
10781                     PackageParser.ServiceIntentInfo[] array =
10782                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
10783                     intentFilters.toArray(array);
10784                     listCut.add(array);
10785                 }
10786             }
10787             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
10788         }
10789 
addService(PackageParser.Service s)10790         public final void addService(PackageParser.Service s) {
10791             mServices.put(s.getComponentName(), s);
10792             if (DEBUG_SHOW_INFO) {
10793                 Log.v(TAG, "  "
10794                         + (s.info.nonLocalizedLabel != null
10795                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
10796                 Log.v(TAG, "    Class=" + s.info.name);
10797             }
10798             final int NI = s.intents.size();
10799             int j;
10800             for (j=0; j<NI; j++) {
10801                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
10802                 if (DEBUG_SHOW_INFO) {
10803                     Log.v(TAG, "    IntentFilter:");
10804                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10805                 }
10806                 if (!intent.debugCheck()) {
10807                     Log.w(TAG, "==> For Service " + s.info.name);
10808                 }
10809                 addFilter(intent);
10810             }
10811         }
10812 
removeService(PackageParser.Service s)10813         public final void removeService(PackageParser.Service s) {
10814             mServices.remove(s.getComponentName());
10815             if (DEBUG_SHOW_INFO) {
10816                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
10817                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
10818                 Log.v(TAG, "    Class=" + s.info.name);
10819             }
10820             final int NI = s.intents.size();
10821             int j;
10822             for (j=0; j<NI; j++) {
10823                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
10824                 if (DEBUG_SHOW_INFO) {
10825                     Log.v(TAG, "    IntentFilter:");
10826                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10827                 }
10828                 removeFilter(intent);
10829             }
10830         }
10831 
10832         @Override
allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)10833         protected boolean allowFilterResult(
10834                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
10835             ServiceInfo filterSi = filter.service.info;
10836             for (int i=dest.size()-1; i>=0; i--) {
10837                 ServiceInfo destAi = dest.get(i).serviceInfo;
10838                 if (destAi.name == filterSi.name
10839                         && destAi.packageName == filterSi.packageName) {
10840                     return false;
10841                 }
10842             }
10843             return true;
10844         }
10845 
10846         @Override
newArray(int size)10847         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
10848             return new PackageParser.ServiceIntentInfo[size];
10849         }
10850 
10851         @Override
isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)10852         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
10853             if (!sUserManager.exists(userId)) return true;
10854             PackageParser.Package p = filter.service.owner;
10855             if (p != null) {
10856                 PackageSetting ps = (PackageSetting)p.mExtras;
10857                 if (ps != null) {
10858                     // System apps are never considered stopped for purposes of
10859                     // filtering, because there may be no way for the user to
10860                     // actually re-launch them.
10861                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
10862                             && ps.getStopped(userId);
10863                 }
10864             }
10865             return false;
10866         }
10867 
10868         @Override
isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)10869         protected boolean isPackageForFilter(String packageName,
10870                 PackageParser.ServiceIntentInfo info) {
10871             return packageName.equals(info.service.owner.packageName);
10872         }
10873 
10874         @Override
newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)10875         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
10876                 int match, int userId) {
10877             if (!sUserManager.exists(userId)) return null;
10878             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
10879             if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
10880                 return null;
10881             }
10882             final PackageParser.Service service = info.service;
10883             PackageSetting ps = (PackageSetting) service.owner.mExtras;
10884             if (ps == null) {
10885                 return null;
10886             }
10887             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
10888                     ps.readUserState(userId), userId);
10889             if (si == null) {
10890                 return null;
10891             }
10892             final ResolveInfo res = new ResolveInfo();
10893             res.serviceInfo = si;
10894             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
10895                 res.filter = filter;
10896             }
10897             res.priority = info.getPriority();
10898             res.preferredOrder = service.owner.mPreferredOrder;
10899             res.match = match;
10900             res.isDefault = info.hasDefault;
10901             res.labelRes = info.labelRes;
10902             res.nonLocalizedLabel = info.nonLocalizedLabel;
10903             res.icon = info.icon;
10904             res.system = res.serviceInfo.applicationInfo.isSystemApp();
10905             return res;
10906         }
10907 
10908         @Override
sortResults(List<ResolveInfo> results)10909         protected void sortResults(List<ResolveInfo> results) {
10910             Collections.sort(results, mResolvePrioritySorter);
10911         }
10912 
10913         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)10914         protected void dumpFilter(PrintWriter out, String prefix,
10915                 PackageParser.ServiceIntentInfo filter) {
10916             out.print(prefix); out.print(
10917                     Integer.toHexString(System.identityHashCode(filter.service)));
10918                     out.print(' ');
10919                     filter.service.printComponentShortName(out);
10920                     out.print(" filter ");
10921                     out.println(Integer.toHexString(System.identityHashCode(filter)));
10922         }
10923 
10924         @Override
filterToLabel(PackageParser.ServiceIntentInfo filter)10925         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
10926             return filter.service;
10927         }
10928 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)10929         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
10930             PackageParser.Service service = (PackageParser.Service)label;
10931             out.print(prefix); out.print(
10932                     Integer.toHexString(System.identityHashCode(service)));
10933                     out.print(' ');
10934                     service.printComponentShortName(out);
10935             if (count > 1) {
10936                 out.print(" ("); out.print(count); out.print(" filters)");
10937             }
10938             out.println();
10939         }
10940 
10941 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
10942 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
10943 //            final List<ResolveInfo> retList = Lists.newArrayList();
10944 //            while (i.hasNext()) {
10945 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
10946 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
10947 //                    retList.add(resolveInfo);
10948 //                }
10949 //            }
10950 //            return retList;
10951 //        }
10952 
10953         // Keys are String (activity class name), values are Activity.
10954         private final ArrayMap<ComponentName, PackageParser.Service> mServices
10955                 = new ArrayMap<ComponentName, PackageParser.Service>();
10956         private int mFlags;
10957     };
10958 
10959     private final class ProviderIntentResolver
10960             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)10961         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10962                 boolean defaultOnly, int userId) {
10963             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10964             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10965         }
10966 
queryIntent(Intent intent, String resolvedType, int flags, int userId)10967         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10968                 int userId) {
10969             if (!sUserManager.exists(userId))
10970                 return null;
10971             mFlags = flags;
10972             return super.queryIntent(intent, resolvedType,
10973                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10974         }
10975 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)10976         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10977                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
10978             if (!sUserManager.exists(userId))
10979                 return null;
10980             if (packageProviders == null) {
10981                 return null;
10982             }
10983             mFlags = flags;
10984             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
10985             final int N = packageProviders.size();
10986             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
10987                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
10988 
10989             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
10990             for (int i = 0; i < N; ++i) {
10991                 intentFilters = packageProviders.get(i).intents;
10992                 if (intentFilters != null && intentFilters.size() > 0) {
10993                     PackageParser.ProviderIntentInfo[] array =
10994                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
10995                     intentFilters.toArray(array);
10996                     listCut.add(array);
10997                 }
10998             }
10999             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11000         }
11001 
addProvider(PackageParser.Provider p)11002         public final void addProvider(PackageParser.Provider p) {
11003             if (mProviders.containsKey(p.getComponentName())) {
11004                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
11005                 return;
11006             }
11007 
11008             mProviders.put(p.getComponentName(), p);
11009             if (DEBUG_SHOW_INFO) {
11010                 Log.v(TAG, "  "
11011                         + (p.info.nonLocalizedLabel != null
11012                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
11013                 Log.v(TAG, "    Class=" + p.info.name);
11014             }
11015             final int NI = p.intents.size();
11016             int j;
11017             for (j = 0; j < NI; j++) {
11018                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11019                 if (DEBUG_SHOW_INFO) {
11020                     Log.v(TAG, "    IntentFilter:");
11021                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11022                 }
11023                 if (!intent.debugCheck()) {
11024                     Log.w(TAG, "==> For Provider " + p.info.name);
11025                 }
11026                 addFilter(intent);
11027             }
11028         }
11029 
removeProvider(PackageParser.Provider p)11030         public final void removeProvider(PackageParser.Provider p) {
11031             mProviders.remove(p.getComponentName());
11032             if (DEBUG_SHOW_INFO) {
11033                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
11034                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
11035                 Log.v(TAG, "    Class=" + p.info.name);
11036             }
11037             final int NI = p.intents.size();
11038             int j;
11039             for (j = 0; j < NI; j++) {
11040                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11041                 if (DEBUG_SHOW_INFO) {
11042                     Log.v(TAG, "    IntentFilter:");
11043                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11044                 }
11045                 removeFilter(intent);
11046             }
11047         }
11048 
11049         @Override
allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)11050         protected boolean allowFilterResult(
11051                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
11052             ProviderInfo filterPi = filter.provider.info;
11053             for (int i = dest.size() - 1; i >= 0; i--) {
11054                 ProviderInfo destPi = dest.get(i).providerInfo;
11055                 if (destPi.name == filterPi.name
11056                         && destPi.packageName == filterPi.packageName) {
11057                     return false;
11058                 }
11059             }
11060             return true;
11061         }
11062 
11063         @Override
newArray(int size)11064         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
11065             return new PackageParser.ProviderIntentInfo[size];
11066         }
11067 
11068         @Override
isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)11069         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
11070             if (!sUserManager.exists(userId))
11071                 return true;
11072             PackageParser.Package p = filter.provider.owner;
11073             if (p != null) {
11074                 PackageSetting ps = (PackageSetting) p.mExtras;
11075                 if (ps != null) {
11076                     // System apps are never considered stopped for purposes of
11077                     // filtering, because there may be no way for the user to
11078                     // actually re-launch them.
11079                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
11080                             && ps.getStopped(userId);
11081                 }
11082             }
11083             return false;
11084         }
11085 
11086         @Override
isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)11087         protected boolean isPackageForFilter(String packageName,
11088                 PackageParser.ProviderIntentInfo info) {
11089             return packageName.equals(info.provider.owner.packageName);
11090         }
11091 
11092         @Override
newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)11093         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
11094                 int match, int userId) {
11095             if (!sUserManager.exists(userId))
11096                 return null;
11097             final PackageParser.ProviderIntentInfo info = filter;
11098             if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
11099                 return null;
11100             }
11101             final PackageParser.Provider provider = info.provider;
11102             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
11103             if (ps == null) {
11104                 return null;
11105             }
11106             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
11107                     ps.readUserState(userId), userId);
11108             if (pi == null) {
11109                 return null;
11110             }
11111             final ResolveInfo res = new ResolveInfo();
11112             res.providerInfo = pi;
11113             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
11114                 res.filter = filter;
11115             }
11116             res.priority = info.getPriority();
11117             res.preferredOrder = provider.owner.mPreferredOrder;
11118             res.match = match;
11119             res.isDefault = info.hasDefault;
11120             res.labelRes = info.labelRes;
11121             res.nonLocalizedLabel = info.nonLocalizedLabel;
11122             res.icon = info.icon;
11123             res.system = res.providerInfo.applicationInfo.isSystemApp();
11124             return res;
11125         }
11126 
11127         @Override
sortResults(List<ResolveInfo> results)11128         protected void sortResults(List<ResolveInfo> results) {
11129             Collections.sort(results, mResolvePrioritySorter);
11130         }
11131 
11132         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)11133         protected void dumpFilter(PrintWriter out, String prefix,
11134                 PackageParser.ProviderIntentInfo filter) {
11135             out.print(prefix);
11136             out.print(
11137                     Integer.toHexString(System.identityHashCode(filter.provider)));
11138             out.print(' ');
11139             filter.provider.printComponentShortName(out);
11140             out.print(" filter ");
11141             out.println(Integer.toHexString(System.identityHashCode(filter)));
11142         }
11143 
11144         @Override
filterToLabel(PackageParser.ProviderIntentInfo filter)11145         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
11146             return filter.provider;
11147         }
11148 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)11149         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11150             PackageParser.Provider provider = (PackageParser.Provider)label;
11151             out.print(prefix); out.print(
11152                     Integer.toHexString(System.identityHashCode(provider)));
11153                     out.print(' ');
11154                     provider.printComponentShortName(out);
11155             if (count > 1) {
11156                 out.print(" ("); out.print(count); out.print(" filters)");
11157             }
11158             out.println();
11159         }
11160 
11161         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
11162                 = new ArrayMap<ComponentName, PackageParser.Provider>();
11163         private int mFlags;
11164     }
11165 
11166     private static final class EphemeralIntentResolver
11167             extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
11168         @Override
newArray(int size)11169         protected EphemeralResolveIntentInfo[] newArray(int size) {
11170             return new EphemeralResolveIntentInfo[size];
11171         }
11172 
11173         @Override
isPackageForFilter(String packageName, EphemeralResolveIntentInfo info)11174         protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
11175             return true;
11176         }
11177 
11178         @Override
newResult(EphemeralResolveIntentInfo info, int match, int userId)11179         protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
11180                 int userId) {
11181             if (!sUserManager.exists(userId)) {
11182                 return null;
11183             }
11184             return info.getEphemeralResolveInfo();
11185         }
11186     }
11187 
11188     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
11189             new Comparator<ResolveInfo>() {
11190         public int compare(ResolveInfo r1, ResolveInfo r2) {
11191             int v1 = r1.priority;
11192             int v2 = r2.priority;
11193             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
11194             if (v1 != v2) {
11195                 return (v1 > v2) ? -1 : 1;
11196             }
11197             v1 = r1.preferredOrder;
11198             v2 = r2.preferredOrder;
11199             if (v1 != v2) {
11200                 return (v1 > v2) ? -1 : 1;
11201             }
11202             if (r1.isDefault != r2.isDefault) {
11203                 return r1.isDefault ? -1 : 1;
11204             }
11205             v1 = r1.match;
11206             v2 = r2.match;
11207             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
11208             if (v1 != v2) {
11209                 return (v1 > v2) ? -1 : 1;
11210             }
11211             if (r1.system != r2.system) {
11212                 return r1.system ? -1 : 1;
11213             }
11214             if (r1.activityInfo != null) {
11215                 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
11216             }
11217             if (r1.serviceInfo != null) {
11218                 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
11219             }
11220             if (r1.providerInfo != null) {
11221                 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
11222             }
11223             return 0;
11224         }
11225     };
11226 
11227     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
11228             new Comparator<ProviderInfo>() {
11229         public int compare(ProviderInfo p1, ProviderInfo p2) {
11230             final int v1 = p1.initOrder;
11231             final int v2 = p2.initOrder;
11232             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
11233         }
11234     };
11235 
sendPackageBroadcast(final String action, final String pkg, final Bundle extras, final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, final int[] userIds)11236     final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
11237             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
11238             final int[] userIds) {
11239         mHandler.post(new Runnable() {
11240             @Override
11241             public void run() {
11242                 try {
11243                     final IActivityManager am = ActivityManagerNative.getDefault();
11244                     if (am == null) return;
11245                     final int[] resolvedUserIds;
11246                     if (userIds == null) {
11247                         resolvedUserIds = am.getRunningUserIds();
11248                     } else {
11249                         resolvedUserIds = userIds;
11250                     }
11251                     for (int id : resolvedUserIds) {
11252                         final Intent intent = new Intent(action,
11253                                 pkg != null ? Uri.fromParts("package", pkg, null) : null);
11254                         if (extras != null) {
11255                             intent.putExtras(extras);
11256                         }
11257                         if (targetPkg != null) {
11258                             intent.setPackage(targetPkg);
11259                         }
11260                         // Modify the UID when posting to other users
11261                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
11262                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
11263                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
11264                             intent.putExtra(Intent.EXTRA_UID, uid);
11265                         }
11266                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
11267                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
11268                         if (DEBUG_BROADCASTS) {
11269                             RuntimeException here = new RuntimeException("here");
11270                             here.fillInStackTrace();
11271                             Slog.d(TAG, "Sending to user " + id + ": "
11272                                     + intent.toShortString(false, true, false, false)
11273                                     + " " + intent.getExtras(), here);
11274                         }
11275                         am.broadcastIntent(null, intent, null, finishedReceiver,
11276                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
11277                                 null, finishedReceiver != null, false, id);
11278                     }
11279                 } catch (RemoteException ex) {
11280                 }
11281             }
11282         });
11283     }
11284 
11285     /**
11286      * Check if the external storage media is available. This is true if there
11287      * is a mounted external storage medium or if the external storage is
11288      * emulated.
11289      */
isExternalMediaAvailable()11290     private boolean isExternalMediaAvailable() {
11291         return mMediaMounted || Environment.isExternalStorageEmulated();
11292     }
11293 
11294     @Override
nextPackageToClean(PackageCleanItem lastPackage)11295     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
11296         // writer
11297         synchronized (mPackages) {
11298             if (!isExternalMediaAvailable()) {
11299                 // If the external storage is no longer mounted at this point,
11300                 // the caller may not have been able to delete all of this
11301                 // packages files and can not delete any more.  Bail.
11302                 return null;
11303             }
11304             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
11305             if (lastPackage != null) {
11306                 pkgs.remove(lastPackage);
11307             }
11308             if (pkgs.size() > 0) {
11309                 return pkgs.get(0);
11310             }
11311         }
11312         return null;
11313     }
11314 
schedulePackageCleaning(String packageName, int userId, boolean andCode)11315     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
11316         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
11317                 userId, andCode ? 1 : 0, packageName);
11318         if (mSystemReady) {
11319             msg.sendToTarget();
11320         } else {
11321             if (mPostSystemReadyMessages == null) {
11322                 mPostSystemReadyMessages = new ArrayList<>();
11323             }
11324             mPostSystemReadyMessages.add(msg);
11325         }
11326     }
11327 
startCleaningPackages()11328     void startCleaningPackages() {
11329         // reader
11330         if (!isExternalMediaAvailable()) {
11331             return;
11332         }
11333         synchronized (mPackages) {
11334             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
11335                 return;
11336             }
11337         }
11338         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
11339         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
11340         IActivityManager am = ActivityManagerNative.getDefault();
11341         if (am != null) {
11342             try {
11343                 am.startService(null, intent, null, mContext.getOpPackageName(),
11344                         UserHandle.USER_SYSTEM);
11345             } catch (RemoteException e) {
11346             }
11347         }
11348     }
11349 
11350     @Override
installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, int userId)11351     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
11352             int installFlags, String installerPackageName, int userId) {
11353         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
11354 
11355         final int callingUid = Binder.getCallingUid();
11356         enforceCrossUserPermission(callingUid, userId,
11357                 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
11358 
11359         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11360             try {
11361                 if (observer != null) {
11362                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
11363                 }
11364             } catch (RemoteException re) {
11365             }
11366             return;
11367         }
11368 
11369         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
11370             installFlags |= PackageManager.INSTALL_FROM_ADB;
11371 
11372         } else {
11373             // Caller holds INSTALL_PACKAGES permission, so we're less strict
11374             // about installerPackageName.
11375 
11376             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
11377             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
11378         }
11379 
11380         UserHandle user;
11381         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
11382             user = UserHandle.ALL;
11383         } else {
11384             user = new UserHandle(userId);
11385         }
11386 
11387         // Only system components can circumvent runtime permissions when installing.
11388         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
11389                 && mContext.checkCallingOrSelfPermission(Manifest.permission
11390                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
11391             throw new SecurityException("You need the "
11392                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
11393                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
11394         }
11395 
11396         final File originFile = new File(originPath);
11397         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
11398 
11399         final Message msg = mHandler.obtainMessage(INIT_COPY);
11400         final VerificationInfo verificationInfo = new VerificationInfo(
11401                 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
11402         final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
11403                 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
11404                 null /*packageAbiOverride*/, null /*grantedPermissions*/,
11405                 null /*certificates*/);
11406         params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
11407         msg.obj = params;
11408 
11409         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
11410                 System.identityHashCode(msg.obj));
11411         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11412                 System.identityHashCode(msg.obj));
11413 
11414         mHandler.sendMessage(msg);
11415     }
11416 
installStage(String packageName, File stagedDir, String stagedCid, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, String installerPackageName, int installerUid, UserHandle user, Certificate[][] certificates)11417     void installStage(String packageName, File stagedDir, String stagedCid,
11418             IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
11419             String installerPackageName, int installerUid, UserHandle user,
11420             Certificate[][] certificates) {
11421         if (DEBUG_EPHEMERAL) {
11422             if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
11423                 Slog.d(TAG, "Ephemeral install of " + packageName);
11424             }
11425         }
11426         final VerificationInfo verificationInfo = new VerificationInfo(
11427                 sessionParams.originatingUri, sessionParams.referrerUri,
11428                 sessionParams.originatingUid, installerUid);
11429 
11430         final OriginInfo origin;
11431         if (stagedDir != null) {
11432             origin = OriginInfo.fromStagedFile(stagedDir);
11433         } else {
11434             origin = OriginInfo.fromStagedContainer(stagedCid);
11435         }
11436 
11437         final Message msg = mHandler.obtainMessage(INIT_COPY);
11438         final InstallParams params = new InstallParams(origin, null, observer,
11439                 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
11440                 verificationInfo, user, sessionParams.abiOverride,
11441                 sessionParams.grantedRuntimePermissions, certificates);
11442         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
11443         msg.obj = params;
11444 
11445         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
11446                 System.identityHashCode(msg.obj));
11447         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11448                 System.identityHashCode(msg.obj));
11449 
11450         mHandler.sendMessage(msg);
11451     }
11452 
sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)11453     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
11454             int userId) {
11455         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
11456         sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
11457     }
11458 
sendPackageAddedForUser(String packageName, boolean isSystem, int appId, int userId)11459     private void sendPackageAddedForUser(String packageName, boolean isSystem,
11460             int appId, int userId) {
11461         Bundle extras = new Bundle(1);
11462         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
11463 
11464         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
11465                 packageName, extras, 0, null, null, new int[] {userId});
11466         try {
11467             IActivityManager am = ActivityManagerNative.getDefault();
11468             if (isSystem && am.isUserRunning(userId, 0)) {
11469                 // The just-installed/enabled app is bundled on the system, so presumed
11470                 // to be able to run automatically without needing an explicit launch.
11471                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
11472                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
11473                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
11474                         .setPackage(packageName);
11475                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
11476                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
11477             }
11478         } catch (RemoteException e) {
11479             // shouldn't happen
11480             Slog.w(TAG, "Unable to bootstrap installed package", e);
11481         }
11482     }
11483 
11484     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)11485     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
11486             int userId) {
11487         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11488         PackageSetting pkgSetting;
11489         final int uid = Binder.getCallingUid();
11490         enforceCrossUserPermission(uid, userId,
11491                 true /* requireFullPermission */, true /* checkShell */,
11492                 "setApplicationHiddenSetting for user " + userId);
11493 
11494         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
11495             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
11496             return false;
11497         }
11498 
11499         long callingId = Binder.clearCallingIdentity();
11500         try {
11501             boolean sendAdded = false;
11502             boolean sendRemoved = false;
11503             // writer
11504             synchronized (mPackages) {
11505                 pkgSetting = mSettings.mPackages.get(packageName);
11506                 if (pkgSetting == null) {
11507                     return false;
11508                 }
11509                 // Do not allow "android" is being disabled
11510                 if ("android".equals(packageName)) {
11511                     Slog.w(TAG, "Cannot hide package: android");
11512                     return false;
11513                 }
11514                 // Only allow protected packages to hide themselves.
11515                 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
11516                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
11517                     Slog.w(TAG, "Not hiding protected package: " + packageName);
11518                     return false;
11519                 }
11520 
11521                 if (pkgSetting.getHidden(userId) != hidden) {
11522                     pkgSetting.setHidden(hidden, userId);
11523                     mSettings.writePackageRestrictionsLPr(userId);
11524                     if (hidden) {
11525                         sendRemoved = true;
11526                     } else {
11527                         sendAdded = true;
11528                     }
11529                 }
11530             }
11531             if (sendAdded) {
11532                 sendPackageAddedForUser(packageName, pkgSetting, userId);
11533                 return true;
11534             }
11535             if (sendRemoved) {
11536                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
11537                         "hiding pkg");
11538                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
11539                 return true;
11540             }
11541         } finally {
11542             Binder.restoreCallingIdentity(callingId);
11543         }
11544         return false;
11545     }
11546 
sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)11547     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
11548             int userId) {
11549         final PackageRemovedInfo info = new PackageRemovedInfo();
11550         info.removedPackage = packageName;
11551         info.removedUsers = new int[] {userId};
11552         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
11553         info.sendPackageRemovedBroadcasts(true /*killApp*/);
11554     }
11555 
sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended)11556     private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
11557         if (pkgList.length > 0) {
11558             Bundle extras = new Bundle(1);
11559             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
11560 
11561             sendPackageBroadcast(
11562                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
11563                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
11564                     null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
11565                     new int[] {userId});
11566         }
11567     }
11568 
11569     /**
11570      * Returns true if application is not found or there was an error. Otherwise it returns
11571      * the hidden state of the package for the given user.
11572      */
11573     @Override
getApplicationHiddenSettingAsUser(String packageName, int userId)11574     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
11575         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11576         enforceCrossUserPermission(Binder.getCallingUid(), userId,
11577                 true /* requireFullPermission */, false /* checkShell */,
11578                 "getApplicationHidden for user " + userId);
11579         PackageSetting pkgSetting;
11580         long callingId = Binder.clearCallingIdentity();
11581         try {
11582             // writer
11583             synchronized (mPackages) {
11584                 pkgSetting = mSettings.mPackages.get(packageName);
11585                 if (pkgSetting == null) {
11586                     return true;
11587                 }
11588                 return pkgSetting.getHidden(userId);
11589             }
11590         } finally {
11591             Binder.restoreCallingIdentity(callingId);
11592         }
11593     }
11594 
11595     /**
11596      * @hide
11597      */
11598     @Override
installExistingPackageAsUser(String packageName, int userId)11599     public int installExistingPackageAsUser(String packageName, int userId) {
11600         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
11601                 null);
11602         PackageSetting pkgSetting;
11603         final int uid = Binder.getCallingUid();
11604         enforceCrossUserPermission(uid, userId,
11605                 true /* requireFullPermission */, true /* checkShell */,
11606                 "installExistingPackage for user " + userId);
11607         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11608             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
11609         }
11610 
11611         long callingId = Binder.clearCallingIdentity();
11612         try {
11613             boolean installed = false;
11614 
11615             // writer
11616             synchronized (mPackages) {
11617                 pkgSetting = mSettings.mPackages.get(packageName);
11618                 if (pkgSetting == null) {
11619                     return PackageManager.INSTALL_FAILED_INVALID_URI;
11620                 }
11621                 if (!pkgSetting.getInstalled(userId)) {
11622                     pkgSetting.setInstalled(true, userId);
11623                     pkgSetting.setHidden(false, userId);
11624                     mSettings.writePackageRestrictionsLPr(userId);
11625                     installed = true;
11626                 }
11627             }
11628 
11629             if (installed) {
11630                 if (pkgSetting.pkg != null) {
11631                     synchronized (mInstallLock) {
11632                         // We don't need to freeze for a brand new install
11633                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
11634                     }
11635                 }
11636                 sendPackageAddedForUser(packageName, pkgSetting, userId);
11637             }
11638         } finally {
11639             Binder.restoreCallingIdentity(callingId);
11640         }
11641 
11642         return PackageManager.INSTALL_SUCCEEDED;
11643     }
11644 
isUserRestricted(int userId, String restrictionKey)11645     boolean isUserRestricted(int userId, String restrictionKey) {
11646         Bundle restrictions = sUserManager.getUserRestrictions(userId);
11647         if (restrictions.getBoolean(restrictionKey, false)) {
11648             Log.w(TAG, "User is restricted: " + restrictionKey);
11649             return true;
11650         }
11651         return false;
11652     }
11653 
11654     @Override
setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, int userId)11655     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
11656             int userId) {
11657         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11658         enforceCrossUserPermission(Binder.getCallingUid(), userId,
11659                 true /* requireFullPermission */, true /* checkShell */,
11660                 "setPackagesSuspended for user " + userId);
11661 
11662         if (ArrayUtils.isEmpty(packageNames)) {
11663             return packageNames;
11664         }
11665 
11666         // List of package names for whom the suspended state has changed.
11667         List<String> changedPackages = new ArrayList<>(packageNames.length);
11668         // List of package names for whom the suspended state is not set as requested in this
11669         // method.
11670         List<String> unactionedPackages = new ArrayList<>(packageNames.length);
11671         long callingId = Binder.clearCallingIdentity();
11672         try {
11673             for (int i = 0; i < packageNames.length; i++) {
11674                 String packageName = packageNames[i];
11675                 boolean changed = false;
11676                 final int appId;
11677                 synchronized (mPackages) {
11678                     final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
11679                     if (pkgSetting == null) {
11680                         Slog.w(TAG, "Could not find package setting for package \"" + packageName
11681                                 + "\". Skipping suspending/un-suspending.");
11682                         unactionedPackages.add(packageName);
11683                         continue;
11684                     }
11685                     appId = pkgSetting.appId;
11686                     if (pkgSetting.getSuspended(userId) != suspended) {
11687                         if (!canSuspendPackageForUserLocked(packageName, userId)) {
11688                             unactionedPackages.add(packageName);
11689                             continue;
11690                         }
11691                         pkgSetting.setSuspended(suspended, userId);
11692                         mSettings.writePackageRestrictionsLPr(userId);
11693                         changed = true;
11694                         changedPackages.add(packageName);
11695                     }
11696                 }
11697 
11698                 if (changed && suspended) {
11699                     killApplication(packageName, UserHandle.getUid(userId, appId),
11700                             "suspending package");
11701                 }
11702             }
11703         } finally {
11704             Binder.restoreCallingIdentity(callingId);
11705         }
11706 
11707         if (!changedPackages.isEmpty()) {
11708             sendPackagesSuspendedForUser(changedPackages.toArray(
11709                     new String[changedPackages.size()]), userId, suspended);
11710         }
11711 
11712         return unactionedPackages.toArray(new String[unactionedPackages.size()]);
11713     }
11714 
11715     @Override
isPackageSuspendedForUser(String packageName, int userId)11716     public boolean isPackageSuspendedForUser(String packageName, int userId) {
11717         enforceCrossUserPermission(Binder.getCallingUid(), userId,
11718                 true /* requireFullPermission */, false /* checkShell */,
11719                 "isPackageSuspendedForUser for user " + userId);
11720         synchronized (mPackages) {
11721             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
11722             if (pkgSetting == null) {
11723                 throw new IllegalArgumentException("Unknown target package: " + packageName);
11724             }
11725             return pkgSetting.getSuspended(userId);
11726         }
11727     }
11728 
canSuspendPackageForUserLocked(String packageName, int userId)11729     private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
11730         if (isPackageDeviceAdmin(packageName, userId)) {
11731             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11732                     + "\": has an active device admin");
11733             return false;
11734         }
11735 
11736         String activeLauncherPackageName = getActiveLauncherPackageName(userId);
11737         if (packageName.equals(activeLauncherPackageName)) {
11738             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11739                     + "\": contains the active launcher");
11740             return false;
11741         }
11742 
11743         if (packageName.equals(mRequiredInstallerPackage)) {
11744             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11745                     + "\": required for package installation");
11746             return false;
11747         }
11748 
11749         if (packageName.equals(mRequiredVerifierPackage)) {
11750             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11751                     + "\": required for package verification");
11752             return false;
11753         }
11754 
11755         if (packageName.equals(getDefaultDialerPackageName(userId))) {
11756             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11757                     + "\": is the default dialer");
11758             return false;
11759         }
11760 
11761         if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
11762             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11763                     + "\": protected package");
11764             return false;
11765         }
11766 
11767         return true;
11768     }
11769 
getActiveLauncherPackageName(int userId)11770     private String getActiveLauncherPackageName(int userId) {
11771         Intent intent = new Intent(Intent.ACTION_MAIN);
11772         intent.addCategory(Intent.CATEGORY_HOME);
11773         ResolveInfo resolveInfo = resolveIntent(
11774                 intent,
11775                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
11776                 PackageManager.MATCH_DEFAULT_ONLY,
11777                 userId);
11778 
11779         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
11780     }
11781 
getDefaultDialerPackageName(int userId)11782     private String getDefaultDialerPackageName(int userId) {
11783         synchronized (mPackages) {
11784             return mSettings.getDefaultDialerPackageNameLPw(userId);
11785         }
11786     }
11787 
11788     @Override
verifyPendingInstall(int id, int verificationCode)11789     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
11790         mContext.enforceCallingOrSelfPermission(
11791                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11792                 "Only package verification agents can verify applications");
11793 
11794         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
11795         final PackageVerificationResponse response = new PackageVerificationResponse(
11796                 verificationCode, Binder.getCallingUid());
11797         msg.arg1 = id;
11798         msg.obj = response;
11799         mHandler.sendMessage(msg);
11800     }
11801 
11802     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)11803     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
11804             long millisecondsToDelay) {
11805         mContext.enforceCallingOrSelfPermission(
11806                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11807                 "Only package verification agents can extend verification timeouts");
11808 
11809         final PackageVerificationState state = mPendingVerification.get(id);
11810         final PackageVerificationResponse response = new PackageVerificationResponse(
11811                 verificationCodeAtTimeout, Binder.getCallingUid());
11812 
11813         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
11814             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
11815         }
11816         if (millisecondsToDelay < 0) {
11817             millisecondsToDelay = 0;
11818         }
11819         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
11820                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
11821             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
11822         }
11823 
11824         if ((state != null) && !state.timeoutExtended()) {
11825             state.extendTimeout();
11826 
11827             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
11828             msg.arg1 = id;
11829             msg.obj = response;
11830             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
11831         }
11832     }
11833 
broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)11834     private void broadcastPackageVerified(int verificationId, Uri packageUri,
11835             int verificationCode, UserHandle user) {
11836         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
11837         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
11838         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
11839         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
11840         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
11841 
11842         mContext.sendBroadcastAsUser(intent, user,
11843                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
11844     }
11845 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)11846     private ComponentName matchComponentForVerifier(String packageName,
11847             List<ResolveInfo> receivers) {
11848         ActivityInfo targetReceiver = null;
11849 
11850         final int NR = receivers.size();
11851         for (int i = 0; i < NR; i++) {
11852             final ResolveInfo info = receivers.get(i);
11853             if (info.activityInfo == null) {
11854                 continue;
11855             }
11856 
11857             if (packageName.equals(info.activityInfo.packageName)) {
11858                 targetReceiver = info.activityInfo;
11859                 break;
11860             }
11861         }
11862 
11863         if (targetReceiver == null) {
11864             return null;
11865         }
11866 
11867         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
11868     }
11869 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)11870     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
11871             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
11872         if (pkgInfo.verifiers.length == 0) {
11873             return null;
11874         }
11875 
11876         final int N = pkgInfo.verifiers.length;
11877         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
11878         for (int i = 0; i < N; i++) {
11879             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
11880 
11881             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
11882                     receivers);
11883             if (comp == null) {
11884                 continue;
11885             }
11886 
11887             final int verifierUid = getUidForVerifier(verifierInfo);
11888             if (verifierUid == -1) {
11889                 continue;
11890             }
11891 
11892             if (DEBUG_VERIFY) {
11893                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
11894                         + " with the correct signature");
11895             }
11896             sufficientVerifiers.add(comp);
11897             verificationState.addSufficientVerifier(verifierUid);
11898         }
11899 
11900         return sufficientVerifiers;
11901     }
11902 
getUidForVerifier(VerifierInfo verifierInfo)11903     private int getUidForVerifier(VerifierInfo verifierInfo) {
11904         synchronized (mPackages) {
11905             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
11906             if (pkg == null) {
11907                 return -1;
11908             } else if (pkg.mSignatures.length != 1) {
11909                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
11910                         + " has more than one signature; ignoring");
11911                 return -1;
11912             }
11913 
11914             /*
11915              * If the public key of the package's signature does not match
11916              * our expected public key, then this is a different package and
11917              * we should skip.
11918              */
11919 
11920             final byte[] expectedPublicKey;
11921             try {
11922                 final Signature verifierSig = pkg.mSignatures[0];
11923                 final PublicKey publicKey = verifierSig.getPublicKey();
11924                 expectedPublicKey = publicKey.getEncoded();
11925             } catch (CertificateException e) {
11926                 return -1;
11927             }
11928 
11929             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
11930 
11931             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
11932                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
11933                         + " does not have the expected public key; ignoring");
11934                 return -1;
11935             }
11936 
11937             return pkg.applicationInfo.uid;
11938         }
11939     }
11940 
11941     @Override
finishPackageInstall(int token, boolean didLaunch)11942     public void finishPackageInstall(int token, boolean didLaunch) {
11943         enforceSystemOrRoot("Only the system is allowed to finish installs");
11944 
11945         if (DEBUG_INSTALL) {
11946             Slog.v(TAG, "BM finishing package install for " + token);
11947         }
11948         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
11949 
11950         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
11951         mHandler.sendMessage(msg);
11952     }
11953 
11954     /**
11955      * Get the verification agent timeout.
11956      *
11957      * @return verification timeout in milliseconds
11958      */
getVerificationTimeout()11959     private long getVerificationTimeout() {
11960         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
11961                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
11962                 DEFAULT_VERIFICATION_TIMEOUT);
11963     }
11964 
11965     /**
11966      * Get the default verification agent response code.
11967      *
11968      * @return default verification response code
11969      */
getDefaultVerificationResponse()11970     private int getDefaultVerificationResponse() {
11971         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11972                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
11973                 DEFAULT_VERIFICATION_RESPONSE);
11974     }
11975 
11976     /**
11977      * Check whether or not package verification has been enabled.
11978      *
11979      * @return true if verification should be performed
11980      */
isVerificationEnabled(int userId, int installFlags)11981     private boolean isVerificationEnabled(int userId, int installFlags) {
11982         if (!DEFAULT_VERIFY_ENABLE) {
11983             return false;
11984         }
11985         // Ephemeral apps don't get the full verification treatment
11986         if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
11987             if (DEBUG_EPHEMERAL) {
11988                 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
11989             }
11990             return false;
11991         }
11992 
11993         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
11994 
11995         // Check if installing from ADB
11996         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
11997             // Do not run verification in a test harness environment
11998             if (ActivityManager.isRunningInTestHarness()) {
11999                 return false;
12000             }
12001             if (ensureVerifyAppsEnabled) {
12002                 return true;
12003             }
12004             // Check if the developer does not want package verification for ADB installs
12005             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12006                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
12007                 return false;
12008             }
12009         }
12010 
12011         if (ensureVerifyAppsEnabled) {
12012             return true;
12013         }
12014 
12015         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12016                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
12017     }
12018 
12019     @Override
verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)12020     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
12021             throws RemoteException {
12022         mContext.enforceCallingOrSelfPermission(
12023                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
12024                 "Only intentfilter verification agents can verify applications");
12025 
12026         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
12027         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
12028                 Binder.getCallingUid(), verificationCode, failedDomains);
12029         msg.arg1 = id;
12030         msg.obj = response;
12031         mHandler.sendMessage(msg);
12032     }
12033 
12034     @Override
getIntentVerificationStatus(String packageName, int userId)12035     public int getIntentVerificationStatus(String packageName, int userId) {
12036         synchronized (mPackages) {
12037             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
12038         }
12039     }
12040 
12041     @Override
updateIntentVerificationStatus(String packageName, int status, int userId)12042     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
12043         mContext.enforceCallingOrSelfPermission(
12044                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12045 
12046         boolean result = false;
12047         synchronized (mPackages) {
12048             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
12049         }
12050         if (result) {
12051             scheduleWritePackageRestrictionsLocked(userId);
12052         }
12053         return result;
12054     }
12055 
12056     @Override
getIntentFilterVerifications( String packageName)12057     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
12058             String packageName) {
12059         synchronized (mPackages) {
12060             return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
12061         }
12062     }
12063 
12064     @Override
getAllIntentFilters(String packageName)12065     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
12066         if (TextUtils.isEmpty(packageName)) {
12067             return ParceledListSlice.emptyList();
12068         }
12069         synchronized (mPackages) {
12070             PackageParser.Package pkg = mPackages.get(packageName);
12071             if (pkg == null || pkg.activities == null) {
12072                 return ParceledListSlice.emptyList();
12073             }
12074             final int count = pkg.activities.size();
12075             ArrayList<IntentFilter> result = new ArrayList<>();
12076             for (int n=0; n<count; n++) {
12077                 PackageParser.Activity activity = pkg.activities.get(n);
12078                 if (activity.intents != null && activity.intents.size() > 0) {
12079                     result.addAll(activity.intents);
12080                 }
12081             }
12082             return new ParceledListSlice<>(result);
12083         }
12084     }
12085 
12086     @Override
setDefaultBrowserPackageName(String packageName, int userId)12087     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
12088         mContext.enforceCallingOrSelfPermission(
12089                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12090 
12091         synchronized (mPackages) {
12092             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
12093             if (packageName != null) {
12094                 result |= updateIntentVerificationStatus(packageName,
12095                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
12096                         userId);
12097                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
12098                         packageName, userId);
12099             }
12100             return result;
12101         }
12102     }
12103 
12104     @Override
getDefaultBrowserPackageName(int userId)12105     public String getDefaultBrowserPackageName(int userId) {
12106         synchronized (mPackages) {
12107             return mSettings.getDefaultBrowserPackageNameLPw(userId);
12108         }
12109     }
12110 
12111     /**
12112      * Get the "allow unknown sources" setting.
12113      *
12114      * @return the current "allow unknown sources" setting
12115      */
getUnknownSourcesSettings()12116     private int getUnknownSourcesSettings() {
12117         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
12118                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
12119                 -1);
12120     }
12121 
12122     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)12123     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
12124         final int uid = Binder.getCallingUid();
12125         // writer
12126         synchronized (mPackages) {
12127             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
12128             if (targetPackageSetting == null) {
12129                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
12130             }
12131 
12132             PackageSetting installerPackageSetting;
12133             if (installerPackageName != null) {
12134                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
12135                 if (installerPackageSetting == null) {
12136                     throw new IllegalArgumentException("Unknown installer package: "
12137                             + installerPackageName);
12138                 }
12139             } else {
12140                 installerPackageSetting = null;
12141             }
12142 
12143             Signature[] callerSignature;
12144             Object obj = mSettings.getUserIdLPr(uid);
12145             if (obj != null) {
12146                 if (obj instanceof SharedUserSetting) {
12147                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
12148                 } else if (obj instanceof PackageSetting) {
12149                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
12150                 } else {
12151                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
12152                 }
12153             } else {
12154                 throw new SecurityException("Unknown calling UID: " + uid);
12155             }
12156 
12157             // Verify: can't set installerPackageName to a package that is
12158             // not signed with the same cert as the caller.
12159             if (installerPackageSetting != null) {
12160                 if (compareSignatures(callerSignature,
12161                         installerPackageSetting.signatures.mSignatures)
12162                         != PackageManager.SIGNATURE_MATCH) {
12163                     throw new SecurityException(
12164                             "Caller does not have same cert as new installer package "
12165                             + installerPackageName);
12166                 }
12167             }
12168 
12169             // Verify: if target already has an installer package, it must
12170             // be signed with the same cert as the caller.
12171             if (targetPackageSetting.installerPackageName != null) {
12172                 PackageSetting setting = mSettings.mPackages.get(
12173                         targetPackageSetting.installerPackageName);
12174                 // If the currently set package isn't valid, then it's always
12175                 // okay to change it.
12176                 if (setting != null) {
12177                     if (compareSignatures(callerSignature,
12178                             setting.signatures.mSignatures)
12179                             != PackageManager.SIGNATURE_MATCH) {
12180                         throw new SecurityException(
12181                                 "Caller does not have same cert as old installer package "
12182                                 + targetPackageSetting.installerPackageName);
12183                     }
12184                 }
12185             }
12186 
12187             // Okay!
12188             targetPackageSetting.installerPackageName = installerPackageName;
12189             if (installerPackageName != null) {
12190                 mSettings.mInstallerPackages.add(installerPackageName);
12191             }
12192             scheduleWriteSettingsLocked();
12193         }
12194     }
12195 
processPendingInstall(final InstallArgs args, final int currentStatus)12196     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
12197         // Queue up an async operation since the package installation may take a little while.
12198         mHandler.post(new Runnable() {
12199             public void run() {
12200                 mHandler.removeCallbacks(this);
12201                  // Result object to be returned
12202                 PackageInstalledInfo res = new PackageInstalledInfo();
12203                 res.setReturnCode(currentStatus);
12204                 res.uid = -1;
12205                 res.pkg = null;
12206                 res.removedInfo = null;
12207                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12208                     args.doPreInstall(res.returnCode);
12209                     synchronized (mInstallLock) {
12210                         installPackageTracedLI(args, res);
12211                     }
12212                     args.doPostInstall(res.returnCode, res.uid);
12213                 }
12214 
12215                 // A restore should be performed at this point if (a) the install
12216                 // succeeded, (b) the operation is not an update, and (c) the new
12217                 // package has not opted out of backup participation.
12218                 final boolean update = res.removedInfo != null
12219                         && res.removedInfo.removedPackage != null;
12220                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
12221                 boolean doRestore = !update
12222                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
12223 
12224                 // Set up the post-install work request bookkeeping.  This will be used
12225                 // and cleaned up by the post-install event handling regardless of whether
12226                 // there's a restore pass performed.  Token values are >= 1.
12227                 int token;
12228                 if (mNextInstallToken < 0) mNextInstallToken = 1;
12229                 token = mNextInstallToken++;
12230 
12231                 PostInstallData data = new PostInstallData(args, res);
12232                 mRunningInstalls.put(token, data);
12233                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
12234 
12235                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
12236                     // Pass responsibility to the Backup Manager.  It will perform a
12237                     // restore if appropriate, then pass responsibility back to the
12238                     // Package Manager to run the post-install observer callbacks
12239                     // and broadcasts.
12240                     IBackupManager bm = IBackupManager.Stub.asInterface(
12241                             ServiceManager.getService(Context.BACKUP_SERVICE));
12242                     if (bm != null) {
12243                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
12244                                 + " to BM for possible restore");
12245                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
12246                         try {
12247                             // TODO: http://b/22388012
12248                             if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
12249                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
12250                             } else {
12251                                 doRestore = false;
12252                             }
12253                         } catch (RemoteException e) {
12254                             // can't happen; the backup manager is local
12255                         } catch (Exception e) {
12256                             Slog.e(TAG, "Exception trying to enqueue restore", e);
12257                             doRestore = false;
12258                         }
12259                     } else {
12260                         Slog.e(TAG, "Backup Manager not found!");
12261                         doRestore = false;
12262                     }
12263                 }
12264 
12265                 if (!doRestore) {
12266                     // No restore possible, or the Backup Manager was mysteriously not
12267                     // available -- just fire the post-install work request directly.
12268                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
12269 
12270                     Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
12271 
12272                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
12273                     mHandler.sendMessage(msg);
12274                 }
12275             }
12276         });
12277     }
12278 
12279     /**
12280      * Callback from PackageSettings whenever an app is first transitioned out of the
12281      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
12282      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
12283      * here whether the app is the target of an ongoing install, and only send the
12284      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
12285      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
12286      * handling.
12287      */
notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId)12288     void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
12289         // Serialize this with the rest of the install-process message chain.  In the
12290         // restore-at-install case, this Runnable will necessarily run before the
12291         // POST_INSTALL message is processed, so the contents of mRunningInstalls
12292         // are coherent.  In the non-restore case, the app has already completed install
12293         // and been launched through some other means, so it is not in a problematic
12294         // state for observers to see the FIRST_LAUNCH signal.
12295         mHandler.post(new Runnable() {
12296             @Override
12297             public void run() {
12298                 for (int i = 0; i < mRunningInstalls.size(); i++) {
12299                     final PostInstallData data = mRunningInstalls.valueAt(i);
12300                     if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12301                         continue;
12302                     }
12303                     if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
12304                         // right package; but is it for the right user?
12305                         for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
12306                             if (userId == data.res.newUsers[uIndex]) {
12307                                 if (DEBUG_BACKUP) {
12308                                     Slog.i(TAG, "Package " + pkgName
12309                                             + " being restored so deferring FIRST_LAUNCH");
12310                                 }
12311                                 return;
12312                             }
12313                         }
12314                     }
12315                 }
12316                 // didn't find it, so not being restored
12317                 if (DEBUG_BACKUP) {
12318                     Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
12319                 }
12320                 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
12321             }
12322         });
12323     }
12324 
sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds)12325     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
12326         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
12327                 installerPkg, null, userIds);
12328     }
12329 
12330     private abstract class HandlerParams {
12331         private static final int MAX_RETRIES = 4;
12332 
12333         /**
12334          * Number of times startCopy() has been attempted and had a non-fatal
12335          * error.
12336          */
12337         private int mRetries = 0;
12338 
12339         /** User handle for the user requesting the information or installation. */
12340         private final UserHandle mUser;
12341         String traceMethod;
12342         int traceCookie;
12343 
HandlerParams(UserHandle user)12344         HandlerParams(UserHandle user) {
12345             mUser = user;
12346         }
12347 
getUser()12348         UserHandle getUser() {
12349             return mUser;
12350         }
12351 
setTraceMethod(String traceMethod)12352         HandlerParams setTraceMethod(String traceMethod) {
12353             this.traceMethod = traceMethod;
12354             return this;
12355         }
12356 
setTraceCookie(int traceCookie)12357         HandlerParams setTraceCookie(int traceCookie) {
12358             this.traceCookie = traceCookie;
12359             return this;
12360         }
12361 
startCopy()12362         final boolean startCopy() {
12363             boolean res;
12364             try {
12365                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
12366 
12367                 if (++mRetries > MAX_RETRIES) {
12368                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
12369                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
12370                     handleServiceError();
12371                     return false;
12372                 } else {
12373                     handleStartCopy();
12374                     res = true;
12375                 }
12376             } catch (RemoteException e) {
12377                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
12378                 mHandler.sendEmptyMessage(MCS_RECONNECT);
12379                 res = false;
12380             }
12381             handleReturnCode();
12382             return res;
12383         }
12384 
serviceError()12385         final void serviceError() {
12386             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
12387             handleServiceError();
12388             handleReturnCode();
12389         }
12390 
12391         abstract void handleStartCopy() throws RemoteException;
12392         abstract void handleServiceError();
12393         abstract void handleReturnCode();
12394     }
12395 
12396     class MeasureParams extends HandlerParams {
12397         private final PackageStats mStats;
12398         private boolean mSuccess;
12399 
12400         private final IPackageStatsObserver mObserver;
12401 
MeasureParams(PackageStats stats, IPackageStatsObserver observer)12402         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
12403             super(new UserHandle(stats.userHandle));
12404             mObserver = observer;
12405             mStats = stats;
12406         }
12407 
12408         @Override
toString()12409         public String toString() {
12410             return "MeasureParams{"
12411                 + Integer.toHexString(System.identityHashCode(this))
12412                 + " " + mStats.packageName + "}";
12413         }
12414 
12415         @Override
handleStartCopy()12416         void handleStartCopy() throws RemoteException {
12417             synchronized (mInstallLock) {
12418                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
12419             }
12420 
12421             if (mSuccess) {
12422                 boolean mounted = false;
12423                 try {
12424                     final String status = Environment.getExternalStorageState();
12425                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
12426                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
12427                 } catch (Exception e) {
12428                 }
12429 
12430                 if (mounted) {
12431                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
12432 
12433                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
12434                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
12435 
12436                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
12437                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
12438 
12439                     // Always subtract cache size, since it's a subdirectory
12440                     mStats.externalDataSize -= mStats.externalCacheSize;
12441 
12442                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
12443                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
12444 
12445                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
12446                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
12447                 }
12448             }
12449         }
12450 
12451         @Override
handleReturnCode()12452         void handleReturnCode() {
12453             if (mObserver != null) {
12454                 try {
12455                     mObserver.onGetStatsCompleted(mStats, mSuccess);
12456                 } catch (RemoteException e) {
12457                     Slog.i(TAG, "Observer no longer exists.");
12458                 }
12459             }
12460         }
12461 
12462         @Override
handleServiceError()12463         void handleServiceError() {
12464             Slog.e(TAG, "Could not measure application " + mStats.packageName
12465                             + " external storage");
12466         }
12467     }
12468 
calculateDirectorySize(IMediaContainerService mcs, File[] paths)12469     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
12470             throws RemoteException {
12471         long result = 0;
12472         for (File path : paths) {
12473             result += mcs.calculateDirectorySize(path.getAbsolutePath());
12474         }
12475         return result;
12476     }
12477 
clearDirectory(IMediaContainerService mcs, File[] paths)12478     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
12479         for (File path : paths) {
12480             try {
12481                 mcs.clearDirectory(path.getAbsolutePath());
12482             } catch (RemoteException e) {
12483             }
12484         }
12485     }
12486 
12487     static class OriginInfo {
12488         /**
12489          * Location where install is coming from, before it has been
12490          * copied/renamed into place. This could be a single monolithic APK
12491          * file, or a cluster directory. This location may be untrusted.
12492          */
12493         final File file;
12494         final String cid;
12495 
12496         /**
12497          * Flag indicating that {@link #file} or {@link #cid} has already been
12498          * staged, meaning downstream users don't need to defensively copy the
12499          * contents.
12500          */
12501         final boolean staged;
12502 
12503         /**
12504          * Flag indicating that {@link #file} or {@link #cid} is an already
12505          * installed app that is being moved.
12506          */
12507         final boolean existing;
12508 
12509         final String resolvedPath;
12510         final File resolvedFile;
12511 
fromNothing()12512         static OriginInfo fromNothing() {
12513             return new OriginInfo(null, null, false, false);
12514         }
12515 
fromUntrustedFile(File file)12516         static OriginInfo fromUntrustedFile(File file) {
12517             return new OriginInfo(file, null, false, false);
12518         }
12519 
fromExistingFile(File file)12520         static OriginInfo fromExistingFile(File file) {
12521             return new OriginInfo(file, null, false, true);
12522         }
12523 
fromStagedFile(File file)12524         static OriginInfo fromStagedFile(File file) {
12525             return new OriginInfo(file, null, true, false);
12526         }
12527 
fromStagedContainer(String cid)12528         static OriginInfo fromStagedContainer(String cid) {
12529             return new OriginInfo(null, cid, true, false);
12530         }
12531 
OriginInfo(File file, String cid, boolean staged, boolean existing)12532         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
12533             this.file = file;
12534             this.cid = cid;
12535             this.staged = staged;
12536             this.existing = existing;
12537 
12538             if (cid != null) {
12539                 resolvedPath = PackageHelper.getSdDir(cid);
12540                 resolvedFile = new File(resolvedPath);
12541             } else if (file != null) {
12542                 resolvedPath = file.getAbsolutePath();
12543                 resolvedFile = file;
12544             } else {
12545                 resolvedPath = null;
12546                 resolvedFile = null;
12547             }
12548         }
12549     }
12550 
12551     static class MoveInfo {
12552         final int moveId;
12553         final String fromUuid;
12554         final String toUuid;
12555         final String packageName;
12556         final String dataAppName;
12557         final int appId;
12558         final String seinfo;
12559         final int targetSdkVersion;
12560 
MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, String dataAppName, int appId, String seinfo, int targetSdkVersion)12561         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
12562                 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
12563             this.moveId = moveId;
12564             this.fromUuid = fromUuid;
12565             this.toUuid = toUuid;
12566             this.packageName = packageName;
12567             this.dataAppName = dataAppName;
12568             this.appId = appId;
12569             this.seinfo = seinfo;
12570             this.targetSdkVersion = targetSdkVersion;
12571         }
12572     }
12573 
12574     static class VerificationInfo {
12575         /** A constant used to indicate that a uid value is not present. */
12576         public static final int NO_UID = -1;
12577 
12578         /** URI referencing where the package was downloaded from. */
12579         final Uri originatingUri;
12580 
12581         /** HTTP referrer URI associated with the originatingURI. */
12582         final Uri referrer;
12583 
12584         /** UID of the application that the install request originated from. */
12585         final int originatingUid;
12586 
12587         /** UID of application requesting the install */
12588         final int installerUid;
12589 
VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid)12590         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
12591             this.originatingUri = originatingUri;
12592             this.referrer = referrer;
12593             this.originatingUid = originatingUid;
12594             this.installerUid = installerUid;
12595         }
12596     }
12597 
12598     class InstallParams extends HandlerParams {
12599         final OriginInfo origin;
12600         final MoveInfo move;
12601         final IPackageInstallObserver2 observer;
12602         int installFlags;
12603         final String installerPackageName;
12604         final String volumeUuid;
12605         private InstallArgs mArgs;
12606         private int mRet;
12607         final String packageAbiOverride;
12608         final String[] grantedRuntimePermissions;
12609         final VerificationInfo verificationInfo;
12610         final Certificate[][] certificates;
12611 
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, String[] grantedPermissions, Certificate[][] certificates)12612         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
12613                 int installFlags, String installerPackageName, String volumeUuid,
12614                 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
12615                 String[] grantedPermissions, Certificate[][] certificates) {
12616             super(user);
12617             this.origin = origin;
12618             this.move = move;
12619             this.observer = observer;
12620             this.installFlags = installFlags;
12621             this.installerPackageName = installerPackageName;
12622             this.volumeUuid = volumeUuid;
12623             this.verificationInfo = verificationInfo;
12624             this.packageAbiOverride = packageAbiOverride;
12625             this.grantedRuntimePermissions = grantedPermissions;
12626             this.certificates = certificates;
12627         }
12628 
12629         @Override
toString()12630         public String toString() {
12631             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
12632                     + " file=" + origin.file + " cid=" + origin.cid + "}";
12633         }
12634 
installLocationPolicy(PackageInfoLite pkgLite)12635         private int installLocationPolicy(PackageInfoLite pkgLite) {
12636             String packageName = pkgLite.packageName;
12637             int installLocation = pkgLite.installLocation;
12638             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
12639             // reader
12640             synchronized (mPackages) {
12641                 // Currently installed package which the new package is attempting to replace or
12642                 // null if no such package is installed.
12643                 PackageParser.Package installedPkg = mPackages.get(packageName);
12644                 // Package which currently owns the data which the new package will own if installed.
12645                 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
12646                 // will be null whereas dataOwnerPkg will contain information about the package
12647                 // which was uninstalled while keeping its data.
12648                 PackageParser.Package dataOwnerPkg = installedPkg;
12649                 if (dataOwnerPkg  == null) {
12650                     PackageSetting ps = mSettings.mPackages.get(packageName);
12651                     if (ps != null) {
12652                         dataOwnerPkg = ps.pkg;
12653                     }
12654                 }
12655 
12656                 if (dataOwnerPkg != null) {
12657                     // If installed, the package will get access to data left on the device by its
12658                     // predecessor. As a security measure, this is permited only if this is not a
12659                     // version downgrade or if the predecessor package is marked as debuggable and
12660                     // a downgrade is explicitly requested.
12661                     //
12662                     // On debuggable platform builds, downgrades are permitted even for
12663                     // non-debuggable packages to make testing easier. Debuggable platform builds do
12664                     // not offer security guarantees and thus it's OK to disable some security
12665                     // mechanisms to make debugging/testing easier on those builds. However, even on
12666                     // debuggable builds downgrades of packages are permitted only if requested via
12667                     // installFlags. This is because we aim to keep the behavior of debuggable
12668                     // platform builds as close as possible to the behavior of non-debuggable
12669                     // platform builds.
12670                     final boolean downgradeRequested =
12671                             (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
12672                     final boolean packageDebuggable =
12673                                 (dataOwnerPkg.applicationInfo.flags
12674                                         & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
12675                     final boolean downgradePermitted =
12676                             (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
12677                     if (!downgradePermitted) {
12678                         try {
12679                             checkDowngrade(dataOwnerPkg, pkgLite);
12680                         } catch (PackageManagerException e) {
12681                             Slog.w(TAG, "Downgrade detected: " + e.getMessage());
12682                             return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
12683                         }
12684                     }
12685                 }
12686 
12687                 if (installedPkg != null) {
12688                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
12689                         // Check for updated system application.
12690                         if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12691                             if (onSd) {
12692                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
12693                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
12694                             }
12695                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
12696                         } else {
12697                             if (onSd) {
12698                                 // Install flag overrides everything.
12699                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
12700                             }
12701                             // If current upgrade specifies particular preference
12702                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
12703                                 // Application explicitly specified internal.
12704                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
12705                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
12706                                 // App explictly prefers external. Let policy decide
12707                             } else {
12708                                 // Prefer previous location
12709                                 if (isExternal(installedPkg)) {
12710                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
12711                                 }
12712                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
12713                             }
12714                         }
12715                     } else {
12716                         // Invalid install. Return error code
12717                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
12718                     }
12719                 }
12720             }
12721             // All the special cases have been taken care of.
12722             // Return result based on recommended install location.
12723             if (onSd) {
12724                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
12725             }
12726             return pkgLite.recommendedInstallLocation;
12727         }
12728 
12729         /*
12730          * Invoke remote method to get package information and install
12731          * location values. Override install location based on default
12732          * policy if needed and then create install arguments based
12733          * on the install location.
12734          */
handleStartCopy()12735         public void handleStartCopy() throws RemoteException {
12736             int ret = PackageManager.INSTALL_SUCCEEDED;
12737 
12738             // If we're already staged, we've firmly committed to an install location
12739             if (origin.staged) {
12740                 if (origin.file != null) {
12741                     installFlags |= PackageManager.INSTALL_INTERNAL;
12742                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
12743                 } else if (origin.cid != null) {
12744                     installFlags |= PackageManager.INSTALL_EXTERNAL;
12745                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
12746                 } else {
12747                     throw new IllegalStateException("Invalid stage location");
12748                 }
12749             }
12750 
12751             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
12752             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
12753             final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
12754             PackageInfoLite pkgLite = null;
12755 
12756             if (onInt && onSd) {
12757                 // Check if both bits are set.
12758                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
12759                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
12760             } else if (onSd && ephemeral) {
12761                 Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
12762                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
12763             } else {
12764                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
12765                         packageAbiOverride);
12766 
12767                 if (DEBUG_EPHEMERAL && ephemeral) {
12768                     Slog.v(TAG, "pkgLite for install: " + pkgLite);
12769                 }
12770 
12771                 /*
12772                  * If we have too little free space, try to free cache
12773                  * before giving up.
12774                  */
12775                 if (!origin.staged && pkgLite.recommendedInstallLocation
12776                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
12777                     // TODO: focus freeing disk space on the target device
12778                     final StorageManager storage = StorageManager.from(mContext);
12779                     final long lowThreshold = storage.getStorageLowBytes(
12780                             Environment.getDataDirectory());
12781 
12782                     final long sizeBytes = mContainerService.calculateInstalledSize(
12783                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
12784 
12785                     try {
12786                         mInstaller.freeCache(null, sizeBytes + lowThreshold);
12787                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
12788                                 installFlags, packageAbiOverride);
12789                     } catch (InstallerException e) {
12790                         Slog.w(TAG, "Failed to free cache", e);
12791                     }
12792 
12793                     /*
12794                      * The cache free must have deleted the file we
12795                      * downloaded to install.
12796                      *
12797                      * TODO: fix the "freeCache" call to not delete
12798                      *       the file we care about.
12799                      */
12800                     if (pkgLite.recommendedInstallLocation
12801                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
12802                         pkgLite.recommendedInstallLocation
12803                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
12804                     }
12805                 }
12806             }
12807 
12808             if (ret == PackageManager.INSTALL_SUCCEEDED) {
12809                 int loc = pkgLite.recommendedInstallLocation;
12810                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
12811                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
12812                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
12813                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
12814                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
12815                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
12816                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
12817                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
12818                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
12819                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
12820                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
12821                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
12822                 } else {
12823                     // Override with defaults if needed.
12824                     loc = installLocationPolicy(pkgLite);
12825                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
12826                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
12827                     } else if (!onSd && !onInt) {
12828                         // Override install location with flags
12829                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
12830                             // Set the flag to install on external media.
12831                             installFlags |= PackageManager.INSTALL_EXTERNAL;
12832                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
12833                         } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
12834                             if (DEBUG_EPHEMERAL) {
12835                                 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
12836                             }
12837                             installFlags |= PackageManager.INSTALL_EPHEMERAL;
12838                             installFlags &= ~(PackageManager.INSTALL_EXTERNAL
12839                                     |PackageManager.INSTALL_INTERNAL);
12840                         } else {
12841                             // Make sure the flag for installing on external
12842                             // media is unset
12843                             installFlags |= PackageManager.INSTALL_INTERNAL;
12844                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
12845                         }
12846                     }
12847                 }
12848             }
12849 
12850             final InstallArgs args = createInstallArgs(this);
12851             mArgs = args;
12852 
12853             if (ret == PackageManager.INSTALL_SUCCEEDED) {
12854                 // TODO: http://b/22976637
12855                 // Apps installed for "all" users use the device owner to verify the app
12856                 UserHandle verifierUser = getUser();
12857                 if (verifierUser == UserHandle.ALL) {
12858                     verifierUser = UserHandle.SYSTEM;
12859                 }
12860 
12861                 /*
12862                  * Determine if we have any installed package verifiers. If we
12863                  * do, then we'll defer to them to verify the packages.
12864                  */
12865                 final int requiredUid = mRequiredVerifierPackage == null ? -1
12866                         : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
12867                                 verifierUser.getIdentifier());
12868                 if (!origin.existing && requiredUid != -1
12869                         && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
12870                     final Intent verification = new Intent(
12871                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
12872                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12873                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
12874                             PACKAGE_MIME_TYPE);
12875                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
12876 
12877                     // Query all live verifiers based on current user state
12878                     final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
12879                             PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
12880 
12881                     if (DEBUG_VERIFY) {
12882                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
12883                                 + verification.toString() + " with " + pkgLite.verifiers.length
12884                                 + " optional verifiers");
12885                     }
12886 
12887                     final int verificationId = mPendingVerificationToken++;
12888 
12889                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
12890 
12891                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
12892                             installerPackageName);
12893 
12894                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
12895                             installFlags);
12896 
12897                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
12898                             pkgLite.packageName);
12899 
12900                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
12901                             pkgLite.versionCode);
12902 
12903                     if (verificationInfo != null) {
12904                         if (verificationInfo.originatingUri != null) {
12905                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
12906                                     verificationInfo.originatingUri);
12907                         }
12908                         if (verificationInfo.referrer != null) {
12909                             verification.putExtra(Intent.EXTRA_REFERRER,
12910                                     verificationInfo.referrer);
12911                         }
12912                         if (verificationInfo.originatingUid >= 0) {
12913                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
12914                                     verificationInfo.originatingUid);
12915                         }
12916                         if (verificationInfo.installerUid >= 0) {
12917                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
12918                                     verificationInfo.installerUid);
12919                         }
12920                     }
12921 
12922                     final PackageVerificationState verificationState = new PackageVerificationState(
12923                             requiredUid, args);
12924 
12925                     mPendingVerification.append(verificationId, verificationState);
12926 
12927                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
12928                             receivers, verificationState);
12929 
12930                     /*
12931                      * If any sufficient verifiers were listed in the package
12932                      * manifest, attempt to ask them.
12933                      */
12934                     if (sufficientVerifiers != null) {
12935                         final int N = sufficientVerifiers.size();
12936                         if (N == 0) {
12937                             Slog.i(TAG, "Additional verifiers required, but none installed.");
12938                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
12939                         } else {
12940                             for (int i = 0; i < N; i++) {
12941                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
12942 
12943                                 final Intent sufficientIntent = new Intent(verification);
12944                                 sufficientIntent.setComponent(verifierComponent);
12945                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
12946                             }
12947                         }
12948                     }
12949 
12950                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
12951                             mRequiredVerifierPackage, receivers);
12952                     if (ret == PackageManager.INSTALL_SUCCEEDED
12953                             && mRequiredVerifierPackage != null) {
12954                         Trace.asyncTraceBegin(
12955                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
12956                         /*
12957                          * Send the intent to the required verification agent,
12958                          * but only start the verification timeout after the
12959                          * target BroadcastReceivers have run.
12960                          */
12961                         verification.setComponent(requiredVerifierComponent);
12962                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
12963                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12964                                 new BroadcastReceiver() {
12965                                     @Override
12966                                     public void onReceive(Context context, Intent intent) {
12967                                         final Message msg = mHandler
12968                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
12969                                         msg.arg1 = verificationId;
12970                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
12971                                     }
12972                                 }, null, 0, null, null);
12973 
12974                         /*
12975                          * We don't want the copy to proceed until verification
12976                          * succeeds, so null out this field.
12977                          */
12978                         mArgs = null;
12979                     }
12980                 } else {
12981                     /*
12982                      * No package verification is enabled, so immediately start
12983                      * the remote call to initiate copy using temporary file.
12984                      */
12985                     ret = args.copyApk(mContainerService, true);
12986                 }
12987             }
12988 
12989             mRet = ret;
12990         }
12991 
12992         @Override
handleReturnCode()12993         void handleReturnCode() {
12994             // If mArgs is null, then MCS couldn't be reached. When it
12995             // reconnects, it will try again to install. At that point, this
12996             // will succeed.
12997             if (mArgs != null) {
12998                 processPendingInstall(mArgs, mRet);
12999             }
13000         }
13001 
13002         @Override
handleServiceError()13003         void handleServiceError() {
13004             mArgs = createInstallArgs(this);
13005             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13006         }
13007 
isForwardLocked()13008         public boolean isForwardLocked() {
13009             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13010         }
13011     }
13012 
13013     /**
13014      * Used during creation of InstallArgs
13015      *
13016      * @param installFlags package installation flags
13017      * @return true if should be installed on external storage
13018      */
installOnExternalAsec(int installFlags)13019     private static boolean installOnExternalAsec(int installFlags) {
13020         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
13021             return false;
13022         }
13023         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13024             return true;
13025         }
13026         return false;
13027     }
13028 
13029     /**
13030      * Used during creation of InstallArgs
13031      *
13032      * @param installFlags package installation flags
13033      * @return true if should be installed as forward locked
13034      */
installForwardLocked(int installFlags)13035     private static boolean installForwardLocked(int installFlags) {
13036         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13037     }
13038 
createInstallArgs(InstallParams params)13039     private InstallArgs createInstallArgs(InstallParams params) {
13040         if (params.move != null) {
13041             return new MoveInstallArgs(params);
13042         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
13043             return new AsecInstallArgs(params);
13044         } else {
13045             return new FileInstallArgs(params);
13046         }
13047     }
13048 
13049     /**
13050      * Create args that describe an existing installed package. Typically used
13051      * when cleaning up old installs, or used as a move source.
13052      */
createInstallArgsForExisting(int installFlags, String codePath, String resourcePath, String[] instructionSets)13053     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
13054             String resourcePath, String[] instructionSets) {
13055         final boolean isInAsec;
13056         if (installOnExternalAsec(installFlags)) {
13057             /* Apps on SD card are always in ASEC containers. */
13058             isInAsec = true;
13059         } else if (installForwardLocked(installFlags)
13060                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
13061             /*
13062              * Forward-locked apps are only in ASEC containers if they're the
13063              * new style
13064              */
13065             isInAsec = true;
13066         } else {
13067             isInAsec = false;
13068         }
13069 
13070         if (isInAsec) {
13071             return new AsecInstallArgs(codePath, instructionSets,
13072                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
13073         } else {
13074             return new FileInstallArgs(codePath, resourcePath, instructionSets);
13075         }
13076     }
13077 
13078     static abstract class InstallArgs {
13079         /** @see InstallParams#origin */
13080         final OriginInfo origin;
13081         /** @see InstallParams#move */
13082         final MoveInfo move;
13083 
13084         final IPackageInstallObserver2 observer;
13085         // Always refers to PackageManager flags only
13086         final int installFlags;
13087         final String installerPackageName;
13088         final String volumeUuid;
13089         final UserHandle user;
13090         final String abiOverride;
13091         final String[] installGrantPermissions;
13092         /** If non-null, drop an async trace when the install completes */
13093         final String traceMethod;
13094         final int traceCookie;
13095         final Certificate[][] certificates;
13096 
13097         // The list of instruction sets supported by this app. This is currently
13098         // only used during the rmdex() phase to clean up resources. We can get rid of this
13099         // if we move dex files under the common app path.
13100         /* nullable */ String[] instructionSets;
13101 
InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, UserHandle user, String[] instructionSets, String abiOverride, String[] installGrantPermissions, String traceMethod, int traceCookie, Certificate[][] certificates)13102         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
13103                 int installFlags, String installerPackageName, String volumeUuid,
13104                 UserHandle user, String[] instructionSets,
13105                 String abiOverride, String[] installGrantPermissions,
13106                 String traceMethod, int traceCookie, Certificate[][] certificates) {
13107             this.origin = origin;
13108             this.move = move;
13109             this.installFlags = installFlags;
13110             this.observer = observer;
13111             this.installerPackageName = installerPackageName;
13112             this.volumeUuid = volumeUuid;
13113             this.user = user;
13114             this.instructionSets = instructionSets;
13115             this.abiOverride = abiOverride;
13116             this.installGrantPermissions = installGrantPermissions;
13117             this.traceMethod = traceMethod;
13118             this.traceCookie = traceCookie;
13119             this.certificates = certificates;
13120         }
13121 
13122         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
13123         abstract int doPreInstall(int status);
13124 
13125         /**
13126          * Rename package into final resting place. All paths on the given
13127          * scanned package should be updated to reflect the rename.
13128          */
13129         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
13130         abstract int doPostInstall(int status, int uid);
13131 
13132         /** @see PackageSettingBase#codePathString */
13133         abstract String getCodePath();
13134         /** @see PackageSettingBase#resourcePathString */
13135         abstract String getResourcePath();
13136 
13137         // Need installer lock especially for dex file removal.
13138         abstract void cleanUpResourcesLI();
13139         abstract boolean doPostDeleteLI(boolean delete);
13140 
13141         /**
13142          * Called before the source arguments are copied. This is used mostly
13143          * for MoveParams when it needs to read the source file to put it in the
13144          * destination.
13145          */
doPreCopy()13146         int doPreCopy() {
13147             return PackageManager.INSTALL_SUCCEEDED;
13148         }
13149 
13150         /**
13151          * Called after the source arguments are copied. This is used mostly for
13152          * MoveParams when it needs to read the source file to put it in the
13153          * destination.
13154          */
doPostCopy(int uid)13155         int doPostCopy(int uid) {
13156             return PackageManager.INSTALL_SUCCEEDED;
13157         }
13158 
isFwdLocked()13159         protected boolean isFwdLocked() {
13160             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13161         }
13162 
isExternalAsec()13163         protected boolean isExternalAsec() {
13164             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
13165         }
13166 
isEphemeral()13167         protected boolean isEphemeral() {
13168             return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13169         }
13170 
getUser()13171         UserHandle getUser() {
13172             return user;
13173         }
13174     }
13175 
removeDexFiles(List<String> allCodePaths, String[] instructionSets)13176     private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
13177         if (!allCodePaths.isEmpty()) {
13178             if (instructionSets == null) {
13179                 throw new IllegalStateException("instructionSet == null");
13180             }
13181             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
13182             for (String codePath : allCodePaths) {
13183                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
13184                     try {
13185                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
13186                     } catch (InstallerException ignored) {
13187                     }
13188                 }
13189             }
13190         }
13191     }
13192 
13193     /**
13194      * Logic to handle installation of non-ASEC applications, including copying
13195      * and renaming logic.
13196      */
13197     class FileInstallArgs extends InstallArgs {
13198         private File codeFile;
13199         private File resourceFile;
13200 
13201         // Example topology:
13202         // /data/app/com.example/base.apk
13203         // /data/app/com.example/split_foo.apk
13204         // /data/app/com.example/lib/arm/libfoo.so
13205         // /data/app/com.example/lib/arm64/libfoo.so
13206         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
13207 
13208         /** New install */
FileInstallArgs(InstallParams params)13209         FileInstallArgs(InstallParams params) {
13210             super(params.origin, params.move, params.observer, params.installFlags,
13211                     params.installerPackageName, params.volumeUuid,
13212                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
13213                     params.grantedRuntimePermissions,
13214                     params.traceMethod, params.traceCookie, params.certificates);
13215             if (isFwdLocked()) {
13216                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
13217             }
13218         }
13219 
13220         /** Existing install */
FileInstallArgs(String codePath, String resourcePath, String[] instructionSets)13221         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
13222             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
13223                     null, null, null, 0, null /*certificates*/);
13224             this.codeFile = (codePath != null) ? new File(codePath) : null;
13225             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
13226         }
13227 
copyApk(IMediaContainerService imcs, boolean temp)13228         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13229             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
13230             try {
13231                 return doCopyApk(imcs, temp);
13232             } finally {
13233                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13234             }
13235         }
13236 
doCopyApk(IMediaContainerService imcs, boolean temp)13237         private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13238             if (origin.staged) {
13239                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
13240                 codeFile = origin.file;
13241                 resourceFile = origin.file;
13242                 return PackageManager.INSTALL_SUCCEEDED;
13243             }
13244 
13245             try {
13246                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13247                 final File tempDir =
13248                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
13249                 codeFile = tempDir;
13250                 resourceFile = tempDir;
13251             } catch (IOException e) {
13252                 Slog.w(TAG, "Failed to create copy file: " + e);
13253                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
13254             }
13255 
13256             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
13257                 @Override
13258                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
13259                     if (!FileUtils.isValidExtFilename(name)) {
13260                         throw new IllegalArgumentException("Invalid filename: " + name);
13261                     }
13262                     try {
13263                         final File file = new File(codeFile, name);
13264                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
13265                                 O_RDWR | O_CREAT, 0644);
13266                         Os.chmod(file.getAbsolutePath(), 0644);
13267                         return new ParcelFileDescriptor(fd);
13268                     } catch (ErrnoException e) {
13269                         throw new RemoteException("Failed to open: " + e.getMessage());
13270                     }
13271                 }
13272             };
13273 
13274             int ret = PackageManager.INSTALL_SUCCEEDED;
13275             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
13276             if (ret != PackageManager.INSTALL_SUCCEEDED) {
13277                 Slog.e(TAG, "Failed to copy package");
13278                 return ret;
13279             }
13280 
13281             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
13282             NativeLibraryHelper.Handle handle = null;
13283             try {
13284                 handle = NativeLibraryHelper.Handle.create(codeFile);
13285                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
13286                         abiOverride);
13287             } catch (IOException e) {
13288                 Slog.e(TAG, "Copying native libraries failed", e);
13289                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13290             } finally {
13291                 IoUtils.closeQuietly(handle);
13292             }
13293 
13294             return ret;
13295         }
13296 
doPreInstall(int status)13297         int doPreInstall(int status) {
13298             if (status != PackageManager.INSTALL_SUCCEEDED) {
13299                 cleanUp();
13300             }
13301             return status;
13302         }
13303 
doRename(int status, PackageParser.Package pkg, String oldCodePath)13304         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13305             if (status != PackageManager.INSTALL_SUCCEEDED) {
13306                 cleanUp();
13307                 return false;
13308             }
13309 
13310             final File targetDir = codeFile.getParentFile();
13311             final File beforeCodeFile = codeFile;
13312             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
13313 
13314             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
13315             try {
13316                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
13317             } catch (ErrnoException e) {
13318                 Slog.w(TAG, "Failed to rename", e);
13319                 return false;
13320             }
13321 
13322             if (!SELinux.restoreconRecursive(afterCodeFile)) {
13323                 Slog.w(TAG, "Failed to restorecon");
13324                 return false;
13325             }
13326 
13327             // Reflect the rename internally
13328             codeFile = afterCodeFile;
13329             resourceFile = afterCodeFile;
13330 
13331             // Reflect the rename in scanned details
13332             pkg.setCodePath(afterCodeFile.getAbsolutePath());
13333             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13334                     afterCodeFile, pkg.baseCodePath));
13335             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13336                     afterCodeFile, pkg.splitCodePaths));
13337 
13338             // Reflect the rename in app info
13339             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13340             pkg.setApplicationInfoCodePath(pkg.codePath);
13341             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13342             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13343             pkg.setApplicationInfoResourcePath(pkg.codePath);
13344             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13345             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13346 
13347             return true;
13348         }
13349 
doPostInstall(int status, int uid)13350         int doPostInstall(int status, int uid) {
13351             if (status != PackageManager.INSTALL_SUCCEEDED) {
13352                 cleanUp();
13353             }
13354             return status;
13355         }
13356 
13357         @Override
getCodePath()13358         String getCodePath() {
13359             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
13360         }
13361 
13362         @Override
getResourcePath()13363         String getResourcePath() {
13364             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
13365         }
13366 
cleanUp()13367         private boolean cleanUp() {
13368             if (codeFile == null || !codeFile.exists()) {
13369                 return false;
13370             }
13371 
13372             removeCodePathLI(codeFile);
13373 
13374             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
13375                 resourceFile.delete();
13376             }
13377 
13378             return true;
13379         }
13380 
cleanUpResourcesLI()13381         void cleanUpResourcesLI() {
13382             // Try enumerating all code paths before deleting
13383             List<String> allCodePaths = Collections.EMPTY_LIST;
13384             if (codeFile != null && codeFile.exists()) {
13385                 try {
13386                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
13387                     allCodePaths = pkg.getAllCodePaths();
13388                 } catch (PackageParserException e) {
13389                     // Ignored; we tried our best
13390                 }
13391             }
13392 
13393             cleanUp();
13394             removeDexFiles(allCodePaths, instructionSets);
13395         }
13396 
doPostDeleteLI(boolean delete)13397         boolean doPostDeleteLI(boolean delete) {
13398             // XXX err, shouldn't we respect the delete flag?
13399             cleanUpResourcesLI();
13400             return true;
13401         }
13402     }
13403 
isAsecExternal(String cid)13404     private boolean isAsecExternal(String cid) {
13405         final String asecPath = PackageHelper.getSdFilesystem(cid);
13406         return !asecPath.startsWith(mAsecInternalPath);
13407     }
13408 
maybeThrowExceptionForMultiArchCopy(String message, int copyRet)13409     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
13410             PackageManagerException {
13411         if (copyRet < 0) {
13412             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
13413                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
13414                 throw new PackageManagerException(copyRet, message);
13415             }
13416         }
13417     }
13418 
13419     /**
13420      * Extract the MountService "container ID" from the full code path of an
13421      * .apk.
13422      */
cidFromCodePath(String fullCodePath)13423     static String cidFromCodePath(String fullCodePath) {
13424         int eidx = fullCodePath.lastIndexOf("/");
13425         String subStr1 = fullCodePath.substring(0, eidx);
13426         int sidx = subStr1.lastIndexOf("/");
13427         return subStr1.substring(sidx+1, eidx);
13428     }
13429 
13430     /**
13431      * Logic to handle installation of ASEC applications, including copying and
13432      * renaming logic.
13433      */
13434     class AsecInstallArgs extends InstallArgs {
13435         static final String RES_FILE_NAME = "pkg.apk";
13436         static final String PUBLIC_RES_FILE_NAME = "res.zip";
13437 
13438         String cid;
13439         String packagePath;
13440         String resourcePath;
13441 
13442         /** New install */
AsecInstallArgs(InstallParams params)13443         AsecInstallArgs(InstallParams params) {
13444             super(params.origin, params.move, params.observer, params.installFlags,
13445                     params.installerPackageName, params.volumeUuid,
13446                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
13447                     params.grantedRuntimePermissions,
13448                     params.traceMethod, params.traceCookie, params.certificates);
13449         }
13450 
13451         /** Existing install */
AsecInstallArgs(String fullCodePath, String[] instructionSets, boolean isExternal, boolean isForwardLocked)13452         AsecInstallArgs(String fullCodePath, String[] instructionSets,
13453                         boolean isExternal, boolean isForwardLocked) {
13454             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
13455               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13456                     instructionSets, null, null, null, 0, null /*certificates*/);
13457             // Hackily pretend we're still looking at a full code path
13458             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
13459                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
13460             }
13461 
13462             // Extract cid from fullCodePath
13463             int eidx = fullCodePath.lastIndexOf("/");
13464             String subStr1 = fullCodePath.substring(0, eidx);
13465             int sidx = subStr1.lastIndexOf("/");
13466             cid = subStr1.substring(sidx+1, eidx);
13467             setMountPath(subStr1);
13468         }
13469 
AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked)13470         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
13471             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
13472               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13473                     instructionSets, null, null, null, 0, null /*certificates*/);
13474             this.cid = cid;
13475             setMountPath(PackageHelper.getSdDir(cid));
13476         }
13477 
createCopyFile()13478         void createCopyFile() {
13479             cid = mInstallerService.allocateExternalStageCidLegacy();
13480         }
13481 
copyApk(IMediaContainerService imcs, boolean temp)13482         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13483             if (origin.staged && origin.cid != null) {
13484                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
13485                 cid = origin.cid;
13486                 setMountPath(PackageHelper.getSdDir(cid));
13487                 return PackageManager.INSTALL_SUCCEEDED;
13488             }
13489 
13490             if (temp) {
13491                 createCopyFile();
13492             } else {
13493                 /*
13494                  * Pre-emptively destroy the container since it's destroyed if
13495                  * copying fails due to it existing anyway.
13496                  */
13497                 PackageHelper.destroySdDir(cid);
13498             }
13499 
13500             final String newMountPath = imcs.copyPackageToContainer(
13501                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
13502                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
13503 
13504             if (newMountPath != null) {
13505                 setMountPath(newMountPath);
13506                 return PackageManager.INSTALL_SUCCEEDED;
13507             } else {
13508                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13509             }
13510         }
13511 
13512         @Override
getCodePath()13513         String getCodePath() {
13514             return packagePath;
13515         }
13516 
13517         @Override
getResourcePath()13518         String getResourcePath() {
13519             return resourcePath;
13520         }
13521 
doPreInstall(int status)13522         int doPreInstall(int status) {
13523             if (status != PackageManager.INSTALL_SUCCEEDED) {
13524                 // Destroy container
13525                 PackageHelper.destroySdDir(cid);
13526             } else {
13527                 boolean mounted = PackageHelper.isContainerMounted(cid);
13528                 if (!mounted) {
13529                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
13530                             Process.SYSTEM_UID);
13531                     if (newMountPath != null) {
13532                         setMountPath(newMountPath);
13533                     } else {
13534                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13535                     }
13536                 }
13537             }
13538             return status;
13539         }
13540 
doRename(int status, PackageParser.Package pkg, String oldCodePath)13541         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13542             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
13543             String newMountPath = null;
13544             if (PackageHelper.isContainerMounted(cid)) {
13545                 // Unmount the container
13546                 if (!PackageHelper.unMountSdDir(cid)) {
13547                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
13548                     return false;
13549                 }
13550             }
13551             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13552                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
13553                         " which might be stale. Will try to clean up.");
13554                 // Clean up the stale container and proceed to recreate.
13555                 if (!PackageHelper.destroySdDir(newCacheId)) {
13556                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
13557                     return false;
13558                 }
13559                 // Successfully cleaned up stale container. Try to rename again.
13560                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13561                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
13562                             + " inspite of cleaning it up.");
13563                     return false;
13564                 }
13565             }
13566             if (!PackageHelper.isContainerMounted(newCacheId)) {
13567                 Slog.w(TAG, "Mounting container " + newCacheId);
13568                 newMountPath = PackageHelper.mountSdDir(newCacheId,
13569                         getEncryptKey(), Process.SYSTEM_UID);
13570             } else {
13571                 newMountPath = PackageHelper.getSdDir(newCacheId);
13572             }
13573             if (newMountPath == null) {
13574                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
13575                 return false;
13576             }
13577             Log.i(TAG, "Succesfully renamed " + cid +
13578                     " to " + newCacheId +
13579                     " at new path: " + newMountPath);
13580             cid = newCacheId;
13581 
13582             final File beforeCodeFile = new File(packagePath);
13583             setMountPath(newMountPath);
13584             final File afterCodeFile = new File(packagePath);
13585 
13586             // Reflect the rename in scanned details
13587             pkg.setCodePath(afterCodeFile.getAbsolutePath());
13588             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13589                     afterCodeFile, pkg.baseCodePath));
13590             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13591                     afterCodeFile, pkg.splitCodePaths));
13592 
13593             // Reflect the rename in app info
13594             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13595             pkg.setApplicationInfoCodePath(pkg.codePath);
13596             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13597             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13598             pkg.setApplicationInfoResourcePath(pkg.codePath);
13599             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13600             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13601 
13602             return true;
13603         }
13604 
setMountPath(String mountPath)13605         private void setMountPath(String mountPath) {
13606             final File mountFile = new File(mountPath);
13607 
13608             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
13609             if (monolithicFile.exists()) {
13610                 packagePath = monolithicFile.getAbsolutePath();
13611                 if (isFwdLocked()) {
13612                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
13613                 } else {
13614                     resourcePath = packagePath;
13615                 }
13616             } else {
13617                 packagePath = mountFile.getAbsolutePath();
13618                 resourcePath = packagePath;
13619             }
13620         }
13621 
doPostInstall(int status, int uid)13622         int doPostInstall(int status, int uid) {
13623             if (status != PackageManager.INSTALL_SUCCEEDED) {
13624                 cleanUp();
13625             } else {
13626                 final int groupOwner;
13627                 final String protectedFile;
13628                 if (isFwdLocked()) {
13629                     groupOwner = UserHandle.getSharedAppGid(uid);
13630                     protectedFile = RES_FILE_NAME;
13631                 } else {
13632                     groupOwner = -1;
13633                     protectedFile = null;
13634                 }
13635 
13636                 if (uid < Process.FIRST_APPLICATION_UID
13637                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
13638                     Slog.e(TAG, "Failed to finalize " + cid);
13639                     PackageHelper.destroySdDir(cid);
13640                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13641                 }
13642 
13643                 boolean mounted = PackageHelper.isContainerMounted(cid);
13644                 if (!mounted) {
13645                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
13646                 }
13647             }
13648             return status;
13649         }
13650 
cleanUp()13651         private void cleanUp() {
13652             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
13653 
13654             // Destroy secure container
13655             PackageHelper.destroySdDir(cid);
13656         }
13657 
getAllCodePaths()13658         private List<String> getAllCodePaths() {
13659             final File codeFile = new File(getCodePath());
13660             if (codeFile != null && codeFile.exists()) {
13661                 try {
13662                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
13663                     return pkg.getAllCodePaths();
13664                 } catch (PackageParserException e) {
13665                     // Ignored; we tried our best
13666                 }
13667             }
13668             return Collections.EMPTY_LIST;
13669         }
13670 
cleanUpResourcesLI()13671         void cleanUpResourcesLI() {
13672             // Enumerate all code paths before deleting
13673             cleanUpResourcesLI(getAllCodePaths());
13674         }
13675 
cleanUpResourcesLI(List<String> allCodePaths)13676         private void cleanUpResourcesLI(List<String> allCodePaths) {
13677             cleanUp();
13678             removeDexFiles(allCodePaths, instructionSets);
13679         }
13680 
getPackageName()13681         String getPackageName() {
13682             return getAsecPackageName(cid);
13683         }
13684 
doPostDeleteLI(boolean delete)13685         boolean doPostDeleteLI(boolean delete) {
13686             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
13687             final List<String> allCodePaths = getAllCodePaths();
13688             boolean mounted = PackageHelper.isContainerMounted(cid);
13689             if (mounted) {
13690                 // Unmount first
13691                 if (PackageHelper.unMountSdDir(cid)) {
13692                     mounted = false;
13693                 }
13694             }
13695             if (!mounted && delete) {
13696                 cleanUpResourcesLI(allCodePaths);
13697             }
13698             return !mounted;
13699         }
13700 
13701         @Override
doPreCopy()13702         int doPreCopy() {
13703             if (isFwdLocked()) {
13704                 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
13705                         MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
13706                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13707                 }
13708             }
13709 
13710             return PackageManager.INSTALL_SUCCEEDED;
13711         }
13712 
13713         @Override
doPostCopy(int uid)13714         int doPostCopy(int uid) {
13715             if (isFwdLocked()) {
13716                 if (uid < Process.FIRST_APPLICATION_UID
13717                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
13718                                 RES_FILE_NAME)) {
13719                     Slog.e(TAG, "Failed to finalize " + cid);
13720                     PackageHelper.destroySdDir(cid);
13721                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13722                 }
13723             }
13724 
13725             return PackageManager.INSTALL_SUCCEEDED;
13726         }
13727     }
13728 
13729     /**
13730      * Logic to handle movement of existing installed applications.
13731      */
13732     class MoveInstallArgs extends InstallArgs {
13733         private File codeFile;
13734         private File resourceFile;
13735 
13736         /** New install */
MoveInstallArgs(InstallParams params)13737         MoveInstallArgs(InstallParams params) {
13738             super(params.origin, params.move, params.observer, params.installFlags,
13739                     params.installerPackageName, params.volumeUuid,
13740                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
13741                     params.grantedRuntimePermissions,
13742                     params.traceMethod, params.traceCookie, params.certificates);
13743         }
13744 
copyApk(IMediaContainerService imcs, boolean temp)13745         int copyApk(IMediaContainerService imcs, boolean temp) {
13746             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
13747                     + move.fromUuid + " to " + move.toUuid);
13748             synchronized (mInstaller) {
13749                 try {
13750                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
13751                             move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
13752                 } catch (InstallerException e) {
13753                     Slog.w(TAG, "Failed to move app", e);
13754                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13755                 }
13756             }
13757 
13758             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
13759             resourceFile = codeFile;
13760             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
13761 
13762             return PackageManager.INSTALL_SUCCEEDED;
13763         }
13764 
doPreInstall(int status)13765         int doPreInstall(int status) {
13766             if (status != PackageManager.INSTALL_SUCCEEDED) {
13767                 cleanUp(move.toUuid);
13768             }
13769             return status;
13770         }
13771 
doRename(int status, PackageParser.Package pkg, String oldCodePath)13772         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13773             if (status != PackageManager.INSTALL_SUCCEEDED) {
13774                 cleanUp(move.toUuid);
13775                 return false;
13776             }
13777 
13778             // Reflect the move in app info
13779             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13780             pkg.setApplicationInfoCodePath(pkg.codePath);
13781             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13782             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13783             pkg.setApplicationInfoResourcePath(pkg.codePath);
13784             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13785             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13786 
13787             return true;
13788         }
13789 
doPostInstall(int status, int uid)13790         int doPostInstall(int status, int uid) {
13791             if (status == PackageManager.INSTALL_SUCCEEDED) {
13792                 cleanUp(move.fromUuid);
13793             } else {
13794                 cleanUp(move.toUuid);
13795             }
13796             return status;
13797         }
13798 
13799         @Override
getCodePath()13800         String getCodePath() {
13801             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
13802         }
13803 
13804         @Override
getResourcePath()13805         String getResourcePath() {
13806             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
13807         }
13808 
cleanUp(String volumeUuid)13809         private boolean cleanUp(String volumeUuid) {
13810             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
13811                     move.dataAppName);
13812             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
13813             final int[] userIds = sUserManager.getUserIds();
13814             synchronized (mInstallLock) {
13815                 // Clean up both app data and code
13816                 // All package moves are frozen until finished
13817                 for (int userId : userIds) {
13818                     try {
13819                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
13820                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
13821                     } catch (InstallerException e) {
13822                         Slog.w(TAG, String.valueOf(e));
13823                     }
13824                 }
13825                 removeCodePathLI(codeFile);
13826             }
13827             return true;
13828         }
13829 
cleanUpResourcesLI()13830         void cleanUpResourcesLI() {
13831             throw new UnsupportedOperationException();
13832         }
13833 
doPostDeleteLI(boolean delete)13834         boolean doPostDeleteLI(boolean delete) {
13835             throw new UnsupportedOperationException();
13836         }
13837     }
13838 
getAsecPackageName(String packageCid)13839     static String getAsecPackageName(String packageCid) {
13840         int idx = packageCid.lastIndexOf("-");
13841         if (idx == -1) {
13842             return packageCid;
13843         }
13844         return packageCid.substring(0, idx);
13845     }
13846 
13847     // Utility method used to create code paths based on package name and available index.
getNextCodePath(String oldCodePath, String prefix, String suffix)13848     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
13849         String idxStr = "";
13850         int idx = 1;
13851         // Fall back to default value of idx=1 if prefix is not
13852         // part of oldCodePath
13853         if (oldCodePath != null) {
13854             String subStr = oldCodePath;
13855             // Drop the suffix right away
13856             if (suffix != null && subStr.endsWith(suffix)) {
13857                 subStr = subStr.substring(0, subStr.length() - suffix.length());
13858             }
13859             // If oldCodePath already contains prefix find out the
13860             // ending index to either increment or decrement.
13861             int sidx = subStr.lastIndexOf(prefix);
13862             if (sidx != -1) {
13863                 subStr = subStr.substring(sidx + prefix.length());
13864                 if (subStr != null) {
13865                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
13866                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
13867                     }
13868                     try {
13869                         idx = Integer.parseInt(subStr);
13870                         if (idx <= 1) {
13871                             idx++;
13872                         } else {
13873                             idx--;
13874                         }
13875                     } catch(NumberFormatException e) {
13876                     }
13877                 }
13878             }
13879         }
13880         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
13881         return prefix + idxStr;
13882     }
13883 
getNextCodePath(File targetDir, String packageName)13884     private File getNextCodePath(File targetDir, String packageName) {
13885         int suffix = 1;
13886         File result;
13887         do {
13888             result = new File(targetDir, packageName + "-" + suffix);
13889             suffix++;
13890         } while (result.exists());
13891         return result;
13892     }
13893 
13894     // Utility method that returns the relative package path with respect
13895     // to the installation directory. Like say for /data/data/com.test-1.apk
13896     // string com.test-1 is returned.
deriveCodePathName(String codePath)13897     static String deriveCodePathName(String codePath) {
13898         if (codePath == null) {
13899             return null;
13900         }
13901         final File codeFile = new File(codePath);
13902         final String name = codeFile.getName();
13903         if (codeFile.isDirectory()) {
13904             return name;
13905         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
13906             final int lastDot = name.lastIndexOf('.');
13907             return name.substring(0, lastDot);
13908         } else {
13909             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
13910             return null;
13911         }
13912     }
13913 
13914     static class PackageInstalledInfo {
13915         String name;
13916         int uid;
13917         // The set of users that originally had this package installed.
13918         int[] origUsers;
13919         // The set of users that now have this package installed.
13920         int[] newUsers;
13921         PackageParser.Package pkg;
13922         int returnCode;
13923         String returnMsg;
13924         PackageRemovedInfo removedInfo;
13925         ArrayMap<String, PackageInstalledInfo> addedChildPackages;
13926 
setError(int code, String msg)13927         public void setError(int code, String msg) {
13928             setReturnCode(code);
13929             setReturnMessage(msg);
13930             Slog.w(TAG, msg);
13931         }
13932 
setError(String msg, PackageParserException e)13933         public void setError(String msg, PackageParserException e) {
13934             setReturnCode(e.error);
13935             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
13936             Slog.w(TAG, msg, e);
13937         }
13938 
setError(String msg, PackageManagerException e)13939         public void setError(String msg, PackageManagerException e) {
13940             returnCode = e.error;
13941             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
13942             Slog.w(TAG, msg, e);
13943         }
13944 
setReturnCode(int returnCode)13945         public void setReturnCode(int returnCode) {
13946             this.returnCode = returnCode;
13947             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
13948             for (int i = 0; i < childCount; i++) {
13949                 addedChildPackages.valueAt(i).returnCode = returnCode;
13950             }
13951         }
13952 
setReturnMessage(String returnMsg)13953         private void setReturnMessage(String returnMsg) {
13954             this.returnMsg = returnMsg;
13955             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
13956             for (int i = 0; i < childCount; i++) {
13957                 addedChildPackages.valueAt(i).returnMsg = returnMsg;
13958             }
13959         }
13960 
13961         // In some error cases we want to convey more info back to the observer
13962         String origPackage;
13963         String origPermission;
13964     }
13965 
13966     /*
13967      * Install a non-existing package.
13968      */
installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, PackageInstalledInfo res)13969     private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
13970             int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
13971             PackageInstalledInfo res) {
13972         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
13973 
13974         // Remember this for later, in case we need to rollback this install
13975         String pkgName = pkg.packageName;
13976 
13977         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
13978 
13979         synchronized(mPackages) {
13980             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
13981                 // A package with the same name is already installed, though
13982                 // it has been renamed to an older name.  The package we
13983                 // are trying to install should be installed as an update to
13984                 // the existing one, but that has not been requested, so bail.
13985                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
13986                         + " without first uninstalling package running as "
13987                         + mSettings.mRenamedPackages.get(pkgName));
13988                 return;
13989             }
13990             if (mPackages.containsKey(pkgName)) {
13991                 // Don't allow installation over an existing package with the same name.
13992                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
13993                         + " without first uninstalling.");
13994                 return;
13995             }
13996         }
13997 
13998         try {
13999             PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
14000                     System.currentTimeMillis(), user);
14001 
14002             updateSettingsLI(newPackage, installerPackageName, null, res, user);
14003 
14004             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14005                 prepareAppDataAfterInstallLIF(newPackage);
14006 
14007             } else {
14008                 // Remove package from internal structures, but keep around any
14009                 // data that might have already existed
14010                 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
14011                         PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
14012             }
14013         } catch (PackageManagerException e) {
14014             res.setError("Package couldn't be installed in " + pkg.codePath, e);
14015         }
14016 
14017         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14018     }
14019 
shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags)14020     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
14021         // Can't rotate keys during boot or if sharedUser.
14022         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
14023                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
14024             return false;
14025         }
14026         // app is using upgradeKeySets; make sure all are valid
14027         KeySetManagerService ksms = mSettings.mKeySetManagerService;
14028         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
14029         for (int i = 0; i < upgradeKeySets.length; i++) {
14030             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
14031                 Slog.wtf(TAG, "Package "
14032                          + (oldPs.name != null ? oldPs.name : "<null>")
14033                          + " contains upgrade-key-set reference to unknown key-set: "
14034                          + upgradeKeySets[i]
14035                          + " reverting to signatures check.");
14036                 return false;
14037             }
14038         }
14039         return true;
14040     }
14041 
checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)14042     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
14043         // Upgrade keysets are being used.  Determine if new package has a superset of the
14044         // required keys.
14045         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
14046         KeySetManagerService ksms = mSettings.mKeySetManagerService;
14047         for (int i = 0; i < upgradeKeySets.length; i++) {
14048             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
14049             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
14050                 return true;
14051             }
14052         }
14053         return false;
14054     }
14055 
updateDigest(MessageDigest digest, File file)14056     private static void updateDigest(MessageDigest digest, File file) throws IOException {
14057         try (DigestInputStream digestStream =
14058                 new DigestInputStream(new FileInputStream(file), digest)) {
14059             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
14060         }
14061     }
14062 
replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res)14063     private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
14064             UserHandle user, String installerPackageName, PackageInstalledInfo res) {
14065         final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
14066 
14067         final PackageParser.Package oldPackage;
14068         final String pkgName = pkg.packageName;
14069         final int[] allUsers;
14070         final int[] installedUsers;
14071 
14072         synchronized(mPackages) {
14073             oldPackage = mPackages.get(pkgName);
14074             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
14075 
14076             // don't allow upgrade to target a release SDK from a pre-release SDK
14077             final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
14078                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14079             final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
14080                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14081             if (oldTargetsPreRelease
14082                     && !newTargetsPreRelease
14083                     && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
14084                 Slog.w(TAG, "Can't install package targeting released sdk");
14085                 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
14086                 return;
14087             }
14088 
14089             // don't allow an upgrade from full to ephemeral
14090             final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
14091             if (isEphemeral && !oldIsEphemeral) {
14092                 // can't downgrade from full to ephemeral
14093                 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
14094                 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
14095                 return;
14096             }
14097 
14098             // verify signatures are valid
14099             final PackageSetting ps = mSettings.mPackages.get(pkgName);
14100             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
14101                 if (!checkUpgradeKeySetLP(ps, pkg)) {
14102                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14103                             "New package not signed by keys specified by upgrade-keysets: "
14104                                     + pkgName);
14105                     return;
14106                 }
14107             } else {
14108                 // default to original signature matching
14109                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
14110                         != PackageManager.SIGNATURE_MATCH) {
14111                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14112                             "New package has a different signature: " + pkgName);
14113                     return;
14114                 }
14115             }
14116 
14117             // don't allow a system upgrade unless the upgrade hash matches
14118             if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
14119                 byte[] digestBytes = null;
14120                 try {
14121                     final MessageDigest digest = MessageDigest.getInstance("SHA-512");
14122                     updateDigest(digest, new File(pkg.baseCodePath));
14123                     if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
14124                         for (String path : pkg.splitCodePaths) {
14125                             updateDigest(digest, new File(path));
14126                         }
14127                     }
14128                     digestBytes = digest.digest();
14129                 } catch (NoSuchAlgorithmException | IOException e) {
14130                     res.setError(INSTALL_FAILED_INVALID_APK,
14131                             "Could not compute hash: " + pkgName);
14132                     return;
14133                 }
14134                 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
14135                     res.setError(INSTALL_FAILED_INVALID_APK,
14136                             "New package fails restrict-update check: " + pkgName);
14137                     return;
14138                 }
14139                 // retain upgrade restriction
14140                 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
14141             }
14142 
14143             // Check for shared user id changes
14144             String invalidPackageName =
14145                     getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
14146             if (invalidPackageName != null) {
14147                 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
14148                         "Package " + invalidPackageName + " tried to change user "
14149                                 + oldPackage.mSharedUserId);
14150                 return;
14151             }
14152 
14153             // In case of rollback, remember per-user/profile install state
14154             allUsers = sUserManager.getUserIds();
14155             installedUsers = ps.queryInstalledUsers(allUsers, true);
14156         }
14157 
14158         // Update what is removed
14159         res.removedInfo = new PackageRemovedInfo();
14160         res.removedInfo.uid = oldPackage.applicationInfo.uid;
14161         res.removedInfo.removedPackage = oldPackage.packageName;
14162         res.removedInfo.isUpdate = true;
14163         res.removedInfo.origUsers = installedUsers;
14164         final int childCount = (oldPackage.childPackages != null)
14165                 ? oldPackage.childPackages.size() : 0;
14166         for (int i = 0; i < childCount; i++) {
14167             boolean childPackageUpdated = false;
14168             PackageParser.Package childPkg = oldPackage.childPackages.get(i);
14169             if (res.addedChildPackages != null) {
14170                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
14171                 if (childRes != null) {
14172                     childRes.removedInfo.uid = childPkg.applicationInfo.uid;
14173                     childRes.removedInfo.removedPackage = childPkg.packageName;
14174                     childRes.removedInfo.isUpdate = true;
14175                     childPackageUpdated = true;
14176                 }
14177             }
14178             if (!childPackageUpdated) {
14179                 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
14180                 childRemovedRes.removedPackage = childPkg.packageName;
14181                 childRemovedRes.isUpdate = false;
14182                 childRemovedRes.dataRemoved = true;
14183                 synchronized (mPackages) {
14184                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
14185                     if (childPs != null) {
14186                         childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
14187                     }
14188                 }
14189                 if (res.removedInfo.removedChildPackages == null) {
14190                     res.removedInfo.removedChildPackages = new ArrayMap<>();
14191                 }
14192                 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
14193             }
14194         }
14195 
14196         boolean sysPkg = (isSystemApp(oldPackage));
14197         if (sysPkg) {
14198             // Set the system/privileged flags as needed
14199             final boolean privileged =
14200                     (oldPackage.applicationInfo.privateFlags
14201                             & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
14202             final int systemPolicyFlags = policyFlags
14203                     | PackageParser.PARSE_IS_SYSTEM
14204                     | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
14205 
14206             replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
14207                     user, allUsers, installerPackageName, res);
14208         } else {
14209             replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
14210                     user, allUsers, installerPackageName, res);
14211         }
14212     }
14213 
getPreviousCodePaths(String packageName)14214     public List<String> getPreviousCodePaths(String packageName) {
14215         final PackageSetting ps = mSettings.mPackages.get(packageName);
14216         final List<String> result = new ArrayList<String>();
14217         if (ps != null && ps.oldCodePaths != null) {
14218             result.addAll(ps.oldCodePaths);
14219         }
14220         return result;
14221     }
14222 
replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, int[] allUsers, String installerPackageName, PackageInstalledInfo res)14223     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
14224             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14225             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14226         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
14227                 + deletedPackage);
14228 
14229         String pkgName = deletedPackage.packageName;
14230         boolean deletedPkg = true;
14231         boolean addedPkg = false;
14232         boolean updatedSettings = false;
14233         final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
14234         final int deleteFlags = PackageManager.DELETE_KEEP_DATA
14235                 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
14236 
14237         final long origUpdateTime = (pkg.mExtras != null)
14238                 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
14239 
14240         // First delete the existing package while retaining the data directory
14241         if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14242                 res.removedInfo, true, pkg)) {
14243             // If the existing package wasn't successfully deleted
14244             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
14245             deletedPkg = false;
14246         } else {
14247             // Successfully deleted the old package; proceed with replace.
14248 
14249             // If deleted package lived in a container, give users a chance to
14250             // relinquish resources before killing.
14251             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
14252                 if (DEBUG_INSTALL) {
14253                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
14254                 }
14255                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
14256                 final ArrayList<String> pkgList = new ArrayList<String>(1);
14257                 pkgList.add(deletedPackage.applicationInfo.packageName);
14258                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
14259             }
14260 
14261             clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14262                     | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14263             clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14264 
14265             try {
14266                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
14267                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
14268                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14269 
14270                 // Update the in-memory copy of the previous code paths.
14271                 PackageSetting ps = mSettings.mPackages.get(pkgName);
14272                 if (!killApp) {
14273                     if (ps.oldCodePaths == null) {
14274                         ps.oldCodePaths = new ArraySet<>();
14275                     }
14276                     Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
14277                     if (deletedPackage.splitCodePaths != null) {
14278                         Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
14279                     }
14280                 } else {
14281                     ps.oldCodePaths = null;
14282                 }
14283                 if (ps.childPackageNames != null) {
14284                     for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
14285                         final String childPkgName = ps.childPackageNames.get(i);
14286                         final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
14287                         childPs.oldCodePaths = ps.oldCodePaths;
14288                     }
14289                 }
14290                 prepareAppDataAfterInstallLIF(newPackage);
14291                 addedPkg = true;
14292             } catch (PackageManagerException e) {
14293                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
14294             }
14295         }
14296 
14297         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14298             if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
14299 
14300             // Revert all internal state mutations and added folders for the failed install
14301             if (addedPkg) {
14302                 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14303                         res.removedInfo, true, null);
14304             }
14305 
14306             // Restore the old package
14307             if (deletedPkg) {
14308                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
14309                 File restoreFile = new File(deletedPackage.codePath);
14310                 // Parse old package
14311                 boolean oldExternal = isExternal(deletedPackage);
14312                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
14313                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
14314                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
14315                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
14316                 try {
14317                     scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
14318                             null);
14319                 } catch (PackageManagerException e) {
14320                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
14321                             + e.getMessage());
14322                     return;
14323                 }
14324 
14325                 synchronized (mPackages) {
14326                     // Ensure the installer package name up to date
14327                     setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14328 
14329                     // Update permissions for restored package
14330                     updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14331 
14332                     mSettings.writeLPr();
14333                 }
14334 
14335                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
14336             }
14337         } else {
14338             synchronized (mPackages) {
14339                 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName);
14340                 if (ps != null) {
14341                     res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
14342                     if (res.removedInfo.removedChildPackages != null) {
14343                         final int childCount = res.removedInfo.removedChildPackages.size();
14344                         // Iterate in reverse as we may modify the collection
14345                         for (int i = childCount - 1; i >= 0; i--) {
14346                             String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
14347                             if (res.addedChildPackages.containsKey(childPackageName)) {
14348                                 res.removedInfo.removedChildPackages.removeAt(i);
14349                             } else {
14350                                 PackageRemovedInfo childInfo = res.removedInfo
14351                                         .removedChildPackages.valueAt(i);
14352                                 childInfo.removedForAllUsers = mPackages.get(
14353                                         childInfo.removedPackage) == null;
14354                             }
14355                         }
14356                     }
14357                 }
14358             }
14359         }
14360     }
14361 
replaceSystemPackageLIF(PackageParser.Package deletedPackage, PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, int[] allUsers, String installerPackageName, PackageInstalledInfo res)14362     private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
14363             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14364             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14365         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
14366                 + ", old=" + deletedPackage);
14367 
14368         final boolean disabledSystem;
14369 
14370         // Remove existing system package
14371         removePackageLI(deletedPackage, true);
14372 
14373         synchronized (mPackages) {
14374             disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
14375         }
14376         if (!disabledSystem) {
14377             // We didn't need to disable the .apk as a current system package,
14378             // which means we are replacing another update that is already
14379             // installed.  We need to make sure to delete the older one's .apk.
14380             res.removedInfo.args = createInstallArgsForExisting(0,
14381                     deletedPackage.applicationInfo.getCodePath(),
14382                     deletedPackage.applicationInfo.getResourcePath(),
14383                     getAppDexInstructionSets(deletedPackage.applicationInfo));
14384         } else {
14385             res.removedInfo.args = null;
14386         }
14387 
14388         // Successfully disabled the old package. Now proceed with re-installation
14389         clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14390                 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14391         clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14392 
14393         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14394         pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
14395                 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
14396 
14397         PackageParser.Package newPackage = null;
14398         try {
14399             // Add the package to the internal data structures
14400             newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
14401 
14402             // Set the update and install times
14403             PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
14404             setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
14405                     System.currentTimeMillis());
14406 
14407             // Update the package dynamic state if succeeded
14408             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14409                 // Now that the install succeeded make sure we remove data
14410                 // directories for any child package the update removed.
14411                 final int deletedChildCount = (deletedPackage.childPackages != null)
14412                         ? deletedPackage.childPackages.size() : 0;
14413                 final int newChildCount = (newPackage.childPackages != null)
14414                         ? newPackage.childPackages.size() : 0;
14415                 for (int i = 0; i < deletedChildCount; i++) {
14416                     PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
14417                     boolean childPackageDeleted = true;
14418                     for (int j = 0; j < newChildCount; j++) {
14419                         PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
14420                         if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
14421                             childPackageDeleted = false;
14422                             break;
14423                         }
14424                     }
14425                     if (childPackageDeleted) {
14426                         PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
14427                                 deletedChildPkg.packageName);
14428                         if (ps != null && res.removedInfo.removedChildPackages != null) {
14429                             PackageRemovedInfo removedChildRes = res.removedInfo
14430                                     .removedChildPackages.get(deletedChildPkg.packageName);
14431                             removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
14432                             removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
14433                         }
14434                     }
14435                 }
14436 
14437                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14438                 prepareAppDataAfterInstallLIF(newPackage);
14439             }
14440         } catch (PackageManagerException e) {
14441             res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
14442             res.setError("Package couldn't be installed in " + pkg.codePath, e);
14443         }
14444 
14445         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14446             // Re installation failed. Restore old information
14447             // Remove new pkg information
14448             if (newPackage != null) {
14449                 removeInstalledPackageLI(newPackage, true);
14450             }
14451             // Add back the old system package
14452             try {
14453                 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
14454             } catch (PackageManagerException e) {
14455                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
14456             }
14457 
14458             synchronized (mPackages) {
14459                 if (disabledSystem) {
14460                     enableSystemPackageLPw(deletedPackage);
14461                 }
14462 
14463                 // Ensure the installer package name up to date
14464                 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14465 
14466                 // Update permissions for restored package
14467                 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14468 
14469                 mSettings.writeLPr();
14470             }
14471 
14472             Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
14473                     + " after failed upgrade");
14474         }
14475     }
14476 
14477     /**
14478      * Checks whether the parent or any of the child packages have a change shared
14479      * user. For a package to be a valid update the shred users of the parent and
14480      * the children should match. We may later support changing child shared users.
14481      * @param oldPkg The updated package.
14482      * @param newPkg The update package.
14483      * @return The shared user that change between the versions.
14484      */
getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, PackageParser.Package newPkg)14485     private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
14486             PackageParser.Package newPkg) {
14487         // Check parent shared user
14488         if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
14489             return newPkg.packageName;
14490         }
14491         // Check child shared users
14492         final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14493         final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
14494         for (int i = 0; i < newChildCount; i++) {
14495             PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
14496             // If this child was present, did it have the same shared user?
14497             for (int j = 0; j < oldChildCount; j++) {
14498                 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
14499                 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
14500                         && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
14501                     return newChildPkg.packageName;
14502                 }
14503             }
14504         }
14505         return null;
14506     }
14507 
removeNativeBinariesLI(PackageSetting ps)14508     private void removeNativeBinariesLI(PackageSetting ps) {
14509         // Remove the lib path for the parent package
14510         if (ps != null) {
14511             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
14512             // Remove the lib path for the child packages
14513             final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
14514             for (int i = 0; i < childCount; i++) {
14515                 PackageSetting childPs = null;
14516                 synchronized (mPackages) {
14517                     childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
14518                 }
14519                 if (childPs != null) {
14520                     NativeLibraryHelper.removeNativeBinariesLI(childPs
14521                             .legacyNativeLibraryPathString);
14522                 }
14523             }
14524         }
14525     }
14526 
enableSystemPackageLPw(PackageParser.Package pkg)14527     private void enableSystemPackageLPw(PackageParser.Package pkg) {
14528         // Enable the parent package
14529         mSettings.enableSystemPackageLPw(pkg.packageName);
14530         // Enable the child packages
14531         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14532         for (int i = 0; i < childCount; i++) {
14533             PackageParser.Package childPkg = pkg.childPackages.get(i);
14534             mSettings.enableSystemPackageLPw(childPkg.packageName);
14535         }
14536     }
14537 
disableSystemPackageLPw(PackageParser.Package oldPkg, PackageParser.Package newPkg)14538     private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
14539             PackageParser.Package newPkg) {
14540         // Disable the parent package (parent always replaced)
14541         boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
14542         // Disable the child packages
14543         final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14544         for (int i = 0; i < childCount; i++) {
14545             PackageParser.Package childPkg = oldPkg.childPackages.get(i);
14546             final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
14547             disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
14548         }
14549         return disabled;
14550     }
14551 
setInstallerPackageNameLPw(PackageParser.Package pkg, String installerPackageName)14552     private void setInstallerPackageNameLPw(PackageParser.Package pkg,
14553             String installerPackageName) {
14554         // Enable the parent package
14555         mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
14556         // Enable the child packages
14557         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14558         for (int i = 0; i < childCount; i++) {
14559             PackageParser.Package childPkg = pkg.childPackages.get(i);
14560             mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
14561         }
14562     }
14563 
revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds)14564     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
14565         // Collect all used permissions in the UID
14566         ArraySet<String> usedPermissions = new ArraySet<>();
14567         final int packageCount = su.packages.size();
14568         for (int i = 0; i < packageCount; i++) {
14569             PackageSetting ps = su.packages.valueAt(i);
14570             if (ps.pkg == null) {
14571                 continue;
14572             }
14573             final int requestedPermCount = ps.pkg.requestedPermissions.size();
14574             for (int j = 0; j < requestedPermCount; j++) {
14575                 String permission = ps.pkg.requestedPermissions.get(j);
14576                 BasePermission bp = mSettings.mPermissions.get(permission);
14577                 if (bp != null) {
14578                     usedPermissions.add(permission);
14579                 }
14580             }
14581         }
14582 
14583         PermissionsState permissionsState = su.getPermissionsState();
14584         // Prune install permissions
14585         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
14586         final int installPermCount = installPermStates.size();
14587         for (int i = installPermCount - 1; i >= 0;  i--) {
14588             PermissionState permissionState = installPermStates.get(i);
14589             if (!usedPermissions.contains(permissionState.getName())) {
14590                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14591                 if (bp != null) {
14592                     permissionsState.revokeInstallPermission(bp);
14593                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
14594                             PackageManager.MASK_PERMISSION_FLAGS, 0);
14595                 }
14596             }
14597         }
14598 
14599         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
14600 
14601         // Prune runtime permissions
14602         for (int userId : allUserIds) {
14603             List<PermissionState> runtimePermStates = permissionsState
14604                     .getRuntimePermissionStates(userId);
14605             final int runtimePermCount = runtimePermStates.size();
14606             for (int i = runtimePermCount - 1; i >= 0; i--) {
14607                 PermissionState permissionState = runtimePermStates.get(i);
14608                 if (!usedPermissions.contains(permissionState.getName())) {
14609                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14610                     if (bp != null) {
14611                         permissionsState.revokeRuntimePermission(bp, userId);
14612                         permissionsState.updatePermissionFlags(bp, userId,
14613                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
14614                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
14615                                 runtimePermissionChangedUserIds, userId);
14616                     }
14617                 }
14618             }
14619         }
14620 
14621         return runtimePermissionChangedUserIds;
14622     }
14623 
updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, PackageInstalledInfo res, UserHandle user)14624     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
14625             int[] allUsers, PackageInstalledInfo res, UserHandle user) {
14626         // Update the parent package setting
14627         updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
14628                 res, user);
14629         // Update the child packages setting
14630         final int childCount = (newPackage.childPackages != null)
14631                 ? newPackage.childPackages.size() : 0;
14632         for (int i = 0; i < childCount; i++) {
14633             PackageParser.Package childPackage = newPackage.childPackages.get(i);
14634             PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
14635             updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
14636                     childRes.origUsers, childRes, user);
14637         }
14638     }
14639 
updateSettingsInternalLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, int[] installedForUsers, PackageInstalledInfo res, UserHandle user)14640     private void updateSettingsInternalLI(PackageParser.Package newPackage,
14641             String installerPackageName, int[] allUsers, int[] installedForUsers,
14642             PackageInstalledInfo res, UserHandle user) {
14643         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
14644 
14645         String pkgName = newPackage.packageName;
14646         synchronized (mPackages) {
14647             //write settings. the installStatus will be incomplete at this stage.
14648             //note that the new package setting would have already been
14649             //added to mPackages. It hasn't been persisted yet.
14650             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
14651             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
14652             mSettings.writeLPr();
14653             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14654         }
14655 
14656         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
14657         synchronized (mPackages) {
14658             updatePermissionsLPw(newPackage.packageName, newPackage,
14659                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
14660                             ? UPDATE_PERMISSIONS_ALL : 0));
14661             // For system-bundled packages, we assume that installing an upgraded version
14662             // of the package implies that the user actually wants to run that new code,
14663             // so we enable the package.
14664             PackageSetting ps = mSettings.mPackages.get(pkgName);
14665             final int userId = user.getIdentifier();
14666             if (ps != null) {
14667                 if (isSystemApp(newPackage)) {
14668                     if (DEBUG_INSTALL) {
14669                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
14670                     }
14671                     // Enable system package for requested users
14672                     if (res.origUsers != null) {
14673                         for (int origUserId : res.origUsers) {
14674                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
14675                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
14676                                         origUserId, installerPackageName);
14677                             }
14678                         }
14679                     }
14680                     // Also convey the prior install/uninstall state
14681                     if (allUsers != null && installedForUsers != null) {
14682                         for (int currentUserId : allUsers) {
14683                             final boolean installed = ArrayUtils.contains(
14684                                     installedForUsers, currentUserId);
14685                             if (DEBUG_INSTALL) {
14686                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
14687                             }
14688                             ps.setInstalled(installed, currentUserId);
14689                         }
14690                         // these install state changes will be persisted in the
14691                         // upcoming call to mSettings.writeLPr().
14692                     }
14693                 }
14694                 // It's implied that when a user requests installation, they want the app to be
14695                 // installed and enabled.
14696                 if (userId != UserHandle.USER_ALL) {
14697                     ps.setInstalled(true, userId);
14698                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
14699                 }
14700             }
14701             res.name = pkgName;
14702             res.uid = newPackage.applicationInfo.uid;
14703             res.pkg = newPackage;
14704             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
14705             mSettings.setInstallerPackageName(pkgName, installerPackageName);
14706             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14707             //to update install status
14708             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
14709             mSettings.writeLPr();
14710             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14711         }
14712 
14713         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14714     }
14715 
installPackageTracedLI(InstallArgs args, PackageInstalledInfo res)14716     private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
14717         try {
14718             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
14719             installPackageLI(args, res);
14720         } finally {
14721             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14722         }
14723     }
14724 
installPackageLI(InstallArgs args, PackageInstalledInfo res)14725     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
14726         final int installFlags = args.installFlags;
14727         final String installerPackageName = args.installerPackageName;
14728         final String volumeUuid = args.volumeUuid;
14729         final File tmpPackageFile = new File(args.getCodePath());
14730         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
14731         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
14732                 || (args.volumeUuid != null));
14733         final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
14734         final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
14735         boolean replace = false;
14736         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
14737         if (args.move != null) {
14738             // moving a complete application; perform an initial scan on the new install location
14739             scanFlags |= SCAN_INITIAL;
14740         }
14741         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
14742             scanFlags |= SCAN_DONT_KILL_APP;
14743         }
14744 
14745         // Result object to be returned
14746         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14747 
14748         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
14749 
14750         // Sanity check
14751         if (ephemeral && (forwardLocked || onExternal)) {
14752             Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
14753                     + " external=" + onExternal);
14754             res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
14755             return;
14756         }
14757 
14758         // Retrieve PackageSettings and parse package
14759         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
14760                 | PackageParser.PARSE_ENFORCE_CODE
14761                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
14762                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
14763                 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0)
14764                 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
14765         PackageParser pp = new PackageParser();
14766         pp.setSeparateProcesses(mSeparateProcesses);
14767         pp.setDisplayMetrics(mMetrics);
14768 
14769         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
14770         final PackageParser.Package pkg;
14771         try {
14772             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
14773         } catch (PackageParserException e) {
14774             res.setError("Failed parse during installPackageLI", e);
14775             return;
14776         } finally {
14777             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14778         }
14779 
14780         // If we are installing a clustered package add results for the children
14781         if (pkg.childPackages != null) {
14782             synchronized (mPackages) {
14783                 final int childCount = pkg.childPackages.size();
14784                 for (int i = 0; i < childCount; i++) {
14785                     PackageParser.Package childPkg = pkg.childPackages.get(i);
14786                     PackageInstalledInfo childRes = new PackageInstalledInfo();
14787                     childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14788                     childRes.pkg = childPkg;
14789                     childRes.name = childPkg.packageName;
14790                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
14791                     if (childPs != null) {
14792                         childRes.origUsers = childPs.queryInstalledUsers(
14793                                 sUserManager.getUserIds(), true);
14794                     }
14795                     if ((mPackages.containsKey(childPkg.packageName))) {
14796                         childRes.removedInfo = new PackageRemovedInfo();
14797                         childRes.removedInfo.removedPackage = childPkg.packageName;
14798                     }
14799                     if (res.addedChildPackages == null) {
14800                         res.addedChildPackages = new ArrayMap<>();
14801                     }
14802                     res.addedChildPackages.put(childPkg.packageName, childRes);
14803                 }
14804             }
14805         }
14806 
14807         // If package doesn't declare API override, mark that we have an install
14808         // time CPU ABI override.
14809         if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
14810             pkg.cpuAbiOverride = args.abiOverride;
14811         }
14812 
14813         String pkgName = res.name = pkg.packageName;
14814         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
14815             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
14816                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
14817                 return;
14818             }
14819         }
14820 
14821         try {
14822             // either use what we've been given or parse directly from the APK
14823             if (args.certificates != null) {
14824                 try {
14825                     PackageParser.populateCertificates(pkg, args.certificates);
14826                 } catch (PackageParserException e) {
14827                     // there was something wrong with the certificates we were given;
14828                     // try to pull them from the APK
14829                     PackageParser.collectCertificates(pkg, parseFlags);
14830                 }
14831             } else {
14832                 PackageParser.collectCertificates(pkg, parseFlags);
14833             }
14834         } catch (PackageParserException e) {
14835             res.setError("Failed collect during installPackageLI", e);
14836             return;
14837         }
14838 
14839         // Get rid of all references to package scan path via parser.
14840         pp = null;
14841         String oldCodePath = null;
14842         boolean systemApp = false;
14843         synchronized (mPackages) {
14844             // Check if installing already existing package
14845             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14846                 String oldName = mSettings.mRenamedPackages.get(pkgName);
14847                 if (pkg.mOriginalPackages != null
14848                         && pkg.mOriginalPackages.contains(oldName)
14849                         && mPackages.containsKey(oldName)) {
14850                     // This package is derived from an original package,
14851                     // and this device has been updating from that original
14852                     // name.  We must continue using the original name, so
14853                     // rename the new package here.
14854                     pkg.setPackageName(oldName);
14855                     pkgName = pkg.packageName;
14856                     replace = true;
14857                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
14858                             + oldName + " pkgName=" + pkgName);
14859                 } else if (mPackages.containsKey(pkgName)) {
14860                     // This package, under its official name, already exists
14861                     // on the device; we should replace it.
14862                     replace = true;
14863                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
14864                 }
14865 
14866                 // Child packages are installed through the parent package
14867                 if (pkg.parentPackage != null) {
14868                     res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
14869                             "Package " + pkg.packageName + " is child of package "
14870                                     + pkg.parentPackage.parentPackage + ". Child packages "
14871                                     + "can be updated only through the parent package.");
14872                     return;
14873                 }
14874 
14875                 if (replace) {
14876                     // Prevent apps opting out from runtime permissions
14877                     PackageParser.Package oldPackage = mPackages.get(pkgName);
14878                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
14879                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
14880                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
14881                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
14882                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
14883                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
14884                                         + " doesn't support runtime permissions but the old"
14885                                         + " target SDK " + oldTargetSdk + " does.");
14886                         return;
14887                     }
14888 
14889                     // Prevent installing of child packages
14890                     if (oldPackage.parentPackage != null) {
14891                         res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
14892                                 "Package " + pkg.packageName + " is child of package "
14893                                         + oldPackage.parentPackage + ". Child packages "
14894                                         + "can be updated only through the parent package.");
14895                         return;
14896                     }
14897                 }
14898             }
14899 
14900             PackageSetting ps = mSettings.mPackages.get(pkgName);
14901             if (ps != null) {
14902                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
14903 
14904                 // Quick sanity check that we're signed correctly if updating;
14905                 // we'll check this again later when scanning, but we want to
14906                 // bail early here before tripping over redefined permissions.
14907                 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
14908                     if (!checkUpgradeKeySetLP(ps, pkg)) {
14909                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
14910                                 + pkg.packageName + " upgrade keys do not match the "
14911                                 + "previously installed version");
14912                         return;
14913                     }
14914                 } else {
14915                     try {
14916                         verifySignaturesLP(ps, pkg);
14917                     } catch (PackageManagerException e) {
14918                         res.setError(e.error, e.getMessage());
14919                         return;
14920                     }
14921                 }
14922 
14923                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
14924                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
14925                     systemApp = (ps.pkg.applicationInfo.flags &
14926                             ApplicationInfo.FLAG_SYSTEM) != 0;
14927                 }
14928                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
14929             }
14930 
14931             // Check whether the newly-scanned package wants to define an already-defined perm
14932             int N = pkg.permissions.size();
14933             for (int i = N-1; i >= 0; i--) {
14934                 PackageParser.Permission perm = pkg.permissions.get(i);
14935                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
14936                 if (bp != null) {
14937                     // If the defining package is signed with our cert, it's okay.  This
14938                     // also includes the "updating the same package" case, of course.
14939                     // "updating same package" could also involve key-rotation.
14940                     final boolean sigsOk;
14941                     if (bp.sourcePackage.equals(pkg.packageName)
14942                             && (bp.packageSetting instanceof PackageSetting)
14943                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
14944                                     scanFlags))) {
14945                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
14946                     } else {
14947                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
14948                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
14949                     }
14950                     if (!sigsOk) {
14951                         // If the owning package is the system itself, we log but allow
14952                         // install to proceed; we fail the install on all other permission
14953                         // redefinitions.
14954                         if (!bp.sourcePackage.equals("android")) {
14955                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
14956                                     + pkg.packageName + " attempting to redeclare permission "
14957                                     + perm.info.name + " already owned by " + bp.sourcePackage);
14958                             res.origPermission = perm.info.name;
14959                             res.origPackage = bp.sourcePackage;
14960                             return;
14961                         } else {
14962                             Slog.w(TAG, "Package " + pkg.packageName
14963                                     + " attempting to redeclare system permission "
14964                                     + perm.info.name + "; ignoring new declaration");
14965                             pkg.permissions.remove(i);
14966                         }
14967                     }
14968                 }
14969             }
14970         }
14971 
14972         if (systemApp) {
14973             if (onExternal) {
14974                 // Abort update; system app can't be replaced with app on sdcard
14975                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
14976                         "Cannot install updates to system apps on sdcard");
14977                 return;
14978             } else if (ephemeral) {
14979                 // Abort update; system app can't be replaced with an ephemeral app
14980                 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
14981                         "Cannot update a system app with an ephemeral app");
14982                 return;
14983             }
14984         }
14985 
14986         if (args.move != null) {
14987             // We did an in-place move, so dex is ready to roll
14988             scanFlags |= SCAN_NO_DEX;
14989             scanFlags |= SCAN_MOVE;
14990 
14991             synchronized (mPackages) {
14992                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
14993                 if (ps == null) {
14994                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
14995                             "Missing settings for moved package " + pkgName);
14996                 }
14997 
14998                 // We moved the entire application as-is, so bring over the
14999                 // previously derived ABI information.
15000                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
15001                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
15002             }
15003 
15004         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
15005             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
15006             scanFlags |= SCAN_NO_DEX;
15007 
15008             try {
15009                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
15010                     args.abiOverride : pkg.cpuAbiOverride);
15011                 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
15012                         true /* extract libs */);
15013             } catch (PackageManagerException pme) {
15014                 Slog.e(TAG, "Error deriving application ABI", pme);
15015                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
15016                 return;
15017             }
15018 
15019             // Shared libraries for the package need to be updated.
15020             synchronized (mPackages) {
15021                 try {
15022                     updateSharedLibrariesLPw(pkg, null);
15023                 } catch (PackageManagerException e) {
15024                     Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage());
15025                 }
15026             }
15027             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
15028             // Do not run PackageDexOptimizer through the local performDexOpt
15029             // method because `pkg` may not be in `mPackages` yet.
15030             //
15031             // Also, don't fail application installs if the dexopt step fails.
15032             mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
15033                     null /* instructionSets */, false /* checkProfiles */,
15034                     getCompilerFilterForReason(REASON_INSTALL),
15035                     getOrCreateCompilerPackageStats(pkg));
15036             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15037 
15038             // Notify BackgroundDexOptService that the package has been changed.
15039             // If this is an update of a package which used to fail to compile,
15040             // BDOS will remove it from its blacklist.
15041             BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
15042         }
15043 
15044         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
15045             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
15046             return;
15047         }
15048 
15049         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
15050 
15051         try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
15052                 "installPackageLI")) {
15053             if (replace) {
15054                 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
15055                         installerPackageName, res);
15056             } else {
15057                 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
15058                         args.user, installerPackageName, volumeUuid, res);
15059             }
15060         }
15061         synchronized (mPackages) {
15062             final PackageSetting ps = mSettings.mPackages.get(pkgName);
15063             if (ps != null) {
15064                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
15065             }
15066 
15067             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15068             for (int i = 0; i < childCount; i++) {
15069                 PackageParser.Package childPkg = pkg.childPackages.get(i);
15070                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15071                 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
15072                 if (childPs != null) {
15073                     childRes.newUsers = childPs.queryInstalledUsers(
15074                             sUserManager.getUserIds(), true);
15075                 }
15076             }
15077         }
15078     }
15079 
startIntentFilterVerifications(int userId, boolean replacing, PackageParser.Package pkg)15080     private void startIntentFilterVerifications(int userId, boolean replacing,
15081             PackageParser.Package pkg) {
15082         if (mIntentFilterVerifierComponent == null) {
15083             Slog.w(TAG, "No IntentFilter verification will not be done as "
15084                     + "there is no IntentFilterVerifier available!");
15085             return;
15086         }
15087 
15088         final int verifierUid = getPackageUid(
15089                 mIntentFilterVerifierComponent.getPackageName(),
15090                 MATCH_DEBUG_TRIAGED_MISSING,
15091                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
15092 
15093         Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15094         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
15095         mHandler.sendMessage(msg);
15096 
15097         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15098         for (int i = 0; i < childCount; i++) {
15099             PackageParser.Package childPkg = pkg.childPackages.get(i);
15100             msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15101             msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
15102             mHandler.sendMessage(msg);
15103         }
15104     }
15105 
verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, PackageParser.Package pkg)15106     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
15107             PackageParser.Package pkg) {
15108         int size = pkg.activities.size();
15109         if (size == 0) {
15110             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15111                     "No activity, so no need to verify any IntentFilter!");
15112             return;
15113         }
15114 
15115         final boolean hasDomainURLs = hasDomainURLs(pkg);
15116         if (!hasDomainURLs) {
15117             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15118                     "No domain URLs, so no need to verify any IntentFilter!");
15119             return;
15120         }
15121 
15122         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
15123                 + " if any IntentFilter from the " + size
15124                 + " Activities needs verification ...");
15125 
15126         int count = 0;
15127         final String packageName = pkg.packageName;
15128 
15129         synchronized (mPackages) {
15130             // If this is a new install and we see that we've already run verification for this
15131             // package, we have nothing to do: it means the state was restored from backup.
15132             if (!replacing) {
15133                 IntentFilterVerificationInfo ivi =
15134                         mSettings.getIntentFilterVerificationLPr(packageName);
15135                 if (ivi != null) {
15136                     if (DEBUG_DOMAIN_VERIFICATION) {
15137                         Slog.i(TAG, "Package " + packageName+ " already verified: status="
15138                                 + ivi.getStatusString());
15139                     }
15140                     return;
15141                 }
15142             }
15143 
15144             // If any filters need to be verified, then all need to be.
15145             boolean needToVerify = false;
15146             for (PackageParser.Activity a : pkg.activities) {
15147                 for (ActivityIntentInfo filter : a.intents) {
15148                     if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
15149                         if (DEBUG_DOMAIN_VERIFICATION) {
15150                             Slog.d(TAG, "Intent filter needs verification, so processing all filters");
15151                         }
15152                         needToVerify = true;
15153                         break;
15154                     }
15155                 }
15156             }
15157 
15158             if (needToVerify) {
15159                 final int verificationId = mIntentFilterVerificationToken++;
15160                 for (PackageParser.Activity a : pkg.activities) {
15161                     for (ActivityIntentInfo filter : a.intents) {
15162                         if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
15163                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15164                                     "Verification needed for IntentFilter:" + filter.toString());
15165                             mIntentFilterVerifier.addOneIntentFilterVerification(
15166                                     verifierUid, userId, verificationId, filter, packageName);
15167                             count++;
15168                         }
15169                     }
15170                 }
15171             }
15172         }
15173 
15174         if (count > 0) {
15175             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
15176                     + " IntentFilter verification" + (count > 1 ? "s" : "")
15177                     +  " for userId:" + userId);
15178             mIntentFilterVerifier.startVerifications(userId);
15179         } else {
15180             if (DEBUG_DOMAIN_VERIFICATION) {
15181                 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
15182             }
15183         }
15184     }
15185 
needsNetworkVerificationLPr(ActivityIntentInfo filter)15186     private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
15187         final ComponentName cn  = filter.activity.getComponentName();
15188         final String packageName = cn.getPackageName();
15189 
15190         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
15191                 packageName);
15192         if (ivi == null) {
15193             return true;
15194         }
15195         int status = ivi.getStatus();
15196         switch (status) {
15197             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
15198             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
15199                 return true;
15200 
15201             default:
15202                 // Nothing to do
15203                 return false;
15204         }
15205     }
15206 
isMultiArch(ApplicationInfo info)15207     private static boolean isMultiArch(ApplicationInfo info) {
15208         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
15209     }
15210 
isExternal(PackageParser.Package pkg)15211     private static boolean isExternal(PackageParser.Package pkg) {
15212         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15213     }
15214 
isExternal(PackageSetting ps)15215     private static boolean isExternal(PackageSetting ps) {
15216         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15217     }
15218 
isEphemeral(PackageParser.Package pkg)15219     private static boolean isEphemeral(PackageParser.Package pkg) {
15220         return pkg.applicationInfo.isEphemeralApp();
15221     }
15222 
isEphemeral(PackageSetting ps)15223     private static boolean isEphemeral(PackageSetting ps) {
15224         return ps.pkg != null && isEphemeral(ps.pkg);
15225     }
15226 
isSystemApp(PackageParser.Package pkg)15227     private static boolean isSystemApp(PackageParser.Package pkg) {
15228         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
15229     }
15230 
isPrivilegedApp(PackageParser.Package pkg)15231     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
15232         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15233     }
15234 
hasDomainURLs(PackageParser.Package pkg)15235     private static boolean hasDomainURLs(PackageParser.Package pkg) {
15236         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
15237     }
15238 
isSystemApp(PackageSetting ps)15239     private static boolean isSystemApp(PackageSetting ps) {
15240         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
15241     }
15242 
isUpdatedSystemApp(PackageSetting ps)15243     private static boolean isUpdatedSystemApp(PackageSetting ps) {
15244         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
15245     }
15246 
packageFlagsToInstallFlags(PackageSetting ps)15247     private int packageFlagsToInstallFlags(PackageSetting ps) {
15248         int installFlags = 0;
15249         if (isEphemeral(ps)) {
15250             installFlags |= PackageManager.INSTALL_EPHEMERAL;
15251         }
15252         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
15253             // This existing package was an external ASEC install when we have
15254             // the external flag without a UUID
15255             installFlags |= PackageManager.INSTALL_EXTERNAL;
15256         }
15257         if (ps.isForwardLocked()) {
15258             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
15259         }
15260         return installFlags;
15261     }
15262 
getVolumeUuidForPackage(PackageParser.Package pkg)15263     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
15264         if (isExternal(pkg)) {
15265             if (TextUtils.isEmpty(pkg.volumeUuid)) {
15266                 return StorageManager.UUID_PRIMARY_PHYSICAL;
15267             } else {
15268                 return pkg.volumeUuid;
15269             }
15270         } else {
15271             return StorageManager.UUID_PRIVATE_INTERNAL;
15272         }
15273     }
15274 
getSettingsVersionForPackage(PackageParser.Package pkg)15275     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
15276         if (isExternal(pkg)) {
15277             if (TextUtils.isEmpty(pkg.volumeUuid)) {
15278                 return mSettings.getExternalVersion();
15279             } else {
15280                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
15281             }
15282         } else {
15283             return mSettings.getInternalVersion();
15284         }
15285     }
15286 
deleteTempPackageFiles()15287     private void deleteTempPackageFiles() {
15288         final FilenameFilter filter = new FilenameFilter() {
15289             public boolean accept(File dir, String name) {
15290                 return name.startsWith("vmdl") && name.endsWith(".tmp");
15291             }
15292         };
15293         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
15294             file.delete();
15295         }
15296     }
15297 
15298     @Override
deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, int flags)15299     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
15300             int flags) {
15301         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
15302                 flags);
15303     }
15304 
15305     @Override
deletePackage(final String packageName, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags)15306     public void deletePackage(final String packageName,
15307             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
15308         mContext.enforceCallingOrSelfPermission(
15309                 android.Manifest.permission.DELETE_PACKAGES, null);
15310         Preconditions.checkNotNull(packageName);
15311         Preconditions.checkNotNull(observer);
15312         final int uid = Binder.getCallingUid();
15313         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
15314         final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
15315         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
15316             mContext.enforceCallingOrSelfPermission(
15317                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15318                     "deletePackage for user " + userId);
15319         }
15320 
15321         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
15322             try {
15323                 observer.onPackageDeleted(packageName,
15324                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
15325             } catch (RemoteException re) {
15326             }
15327             return;
15328         }
15329 
15330         if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) {
15331             try {
15332                 observer.onPackageDeleted(packageName,
15333                         PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
15334             } catch (RemoteException re) {
15335             }
15336             return;
15337         }
15338 
15339         if (DEBUG_REMOVE) {
15340             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId
15341                     + " deleteAllUsers: " + deleteAllUsers );
15342         }
15343         // Queue up an async operation since the package deletion may take a little while.
15344         mHandler.post(new Runnable() {
15345             public void run() {
15346                 mHandler.removeCallbacks(this);
15347                 int returnCode;
15348                 if (!deleteAllUsers) {
15349                     returnCode = deletePackageX(packageName, userId, deleteFlags);
15350                 } else {
15351                     int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users);
15352                     // If nobody is blocking uninstall, proceed with delete for all users
15353                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
15354                         returnCode = deletePackageX(packageName, userId, deleteFlags);
15355                     } else {
15356                         // Otherwise uninstall individually for users with blockUninstalls=false
15357                         final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
15358                         for (int userId : users) {
15359                             if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
15360                                 returnCode = deletePackageX(packageName, userId, userFlags);
15361                                 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
15362                                     Slog.w(TAG, "Package delete failed for user " + userId
15363                                             + ", returnCode " + returnCode);
15364                                 }
15365                             }
15366                         }
15367                         // The app has only been marked uninstalled for certain users.
15368                         // We still need to report that delete was blocked
15369                         returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
15370                     }
15371                 }
15372                 try {
15373                     observer.onPackageDeleted(packageName, returnCode, null);
15374                 } catch (RemoteException e) {
15375                     Log.i(TAG, "Observer no longer exists.");
15376                 } //end catch
15377             } //end run
15378         });
15379     }
15380 
getBlockUninstallForUsers(String packageName, int[] userIds)15381     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
15382         int[] result = EMPTY_INT_ARRAY;
15383         for (int userId : userIds) {
15384             if (getBlockUninstallForUser(packageName, userId)) {
15385                 result = ArrayUtils.appendInt(result, userId);
15386             }
15387         }
15388         return result;
15389     }
15390 
15391     @Override
isPackageDeviceAdminOnAnyUser(String packageName)15392     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
15393         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
15394     }
15395 
isPackageDeviceAdmin(String packageName, int userId)15396     private boolean isPackageDeviceAdmin(String packageName, int userId) {
15397         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
15398                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
15399         try {
15400             if (dpm != null) {
15401                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
15402                         /* callingUserOnly =*/ false);
15403                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
15404                         : deviceOwnerComponentName.getPackageName();
15405                 // Does the package contains the device owner?
15406                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
15407                 // this check is probably not needed, since DO should be registered as a device
15408                 // admin on some user too. (Original bug for this: b/17657954)
15409                 if (packageName.equals(deviceOwnerPackageName)) {
15410                     return true;
15411                 }
15412                 // Does it contain a device admin for any user?
15413                 int[] users;
15414                 if (userId == UserHandle.USER_ALL) {
15415                     users = sUserManager.getUserIds();
15416                 } else {
15417                     users = new int[]{userId};
15418                 }
15419                 for (int i = 0; i < users.length; ++i) {
15420                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
15421                         return true;
15422                     }
15423                 }
15424             }
15425         } catch (RemoteException e) {
15426         }
15427         return false;
15428     }
15429 
shouldKeepUninstalledPackageLPr(String packageName)15430     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
15431         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
15432     }
15433 
15434     /**
15435      *  This method is an internal method that could be get invoked either
15436      *  to delete an installed package or to clean up a failed installation.
15437      *  After deleting an installed package, a broadcast is sent to notify any
15438      *  listeners that the package has been removed. For cleaning up a failed
15439      *  installation, the broadcast is not necessary since the package's
15440      *  installation wouldn't have sent the initial broadcast either
15441      *  The key steps in deleting a package are
15442      *  deleting the package information in internal structures like mPackages,
15443      *  deleting the packages base directories through installd
15444      *  updating mSettings to reflect current status
15445      *  persisting settings for later use
15446      *  sending a broadcast if necessary
15447      */
deletePackageX(String packageName, int userId, int deleteFlags)15448     private int deletePackageX(String packageName, int userId, int deleteFlags) {
15449         final PackageRemovedInfo info = new PackageRemovedInfo();
15450         final boolean res;
15451 
15452         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
15453                 ? UserHandle.USER_ALL : userId;
15454 
15455         if (isPackageDeviceAdmin(packageName, removeUser)) {
15456             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
15457             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
15458         }
15459 
15460         PackageSetting uninstalledPs = null;
15461 
15462         // for the uninstall-updates case and restricted profiles, remember the per-
15463         // user handle installed state
15464         int[] allUsers;
15465         synchronized (mPackages) {
15466             uninstalledPs = mSettings.mPackages.get(packageName);
15467             if (uninstalledPs == null) {
15468                 Slog.w(TAG, "Not removing non-existent package " + packageName);
15469                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15470             }
15471             allUsers = sUserManager.getUserIds();
15472             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
15473         }
15474 
15475         final int freezeUser;
15476         if (isUpdatedSystemApp(uninstalledPs)
15477                 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
15478             // We're downgrading a system app, which will apply to all users, so
15479             // freeze them all during the downgrade
15480             freezeUser = UserHandle.USER_ALL;
15481         } else {
15482             freezeUser = removeUser;
15483         }
15484 
15485         synchronized (mInstallLock) {
15486             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
15487             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
15488                     deleteFlags, "deletePackageX")) {
15489                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
15490                         deleteFlags | REMOVE_CHATTY, info, true, null);
15491             }
15492             synchronized (mPackages) {
15493                 if (res) {
15494                     mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
15495                 }
15496             }
15497         }
15498 
15499         if (res) {
15500             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
15501             info.sendPackageRemovedBroadcasts(killApp);
15502             info.sendSystemPackageUpdatedBroadcasts();
15503             info.sendSystemPackageAppearedBroadcasts();
15504         }
15505         // Force a gc here.
15506         Runtime.getRuntime().gc();
15507         // Delete the resources here after sending the broadcast to let
15508         // other processes clean up before deleting resources.
15509         if (info.args != null) {
15510             synchronized (mInstallLock) {
15511                 info.args.doPostDeleteLI(true);
15512             }
15513         }
15514 
15515         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15516     }
15517 
15518     class PackageRemovedInfo {
15519         String removedPackage;
15520         int uid = -1;
15521         int removedAppId = -1;
15522         int[] origUsers;
15523         int[] removedUsers = null;
15524         boolean isRemovedPackageSystemUpdate = false;
15525         boolean isUpdate;
15526         boolean dataRemoved;
15527         boolean removedForAllUsers;
15528         // Clean up resources deleted packages.
15529         InstallArgs args = null;
15530         ArrayMap<String, PackageRemovedInfo> removedChildPackages;
15531         ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
15532 
sendPackageRemovedBroadcasts(boolean killApp)15533         void sendPackageRemovedBroadcasts(boolean killApp) {
15534             sendPackageRemovedBroadcastInternal(killApp);
15535             final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
15536             for (int i = 0; i < childCount; i++) {
15537                 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15538                 childInfo.sendPackageRemovedBroadcastInternal(killApp);
15539             }
15540         }
15541 
sendSystemPackageUpdatedBroadcasts()15542         void sendSystemPackageUpdatedBroadcasts() {
15543             if (isRemovedPackageSystemUpdate) {
15544                 sendSystemPackageUpdatedBroadcastsInternal();
15545                 final int childCount = (removedChildPackages != null)
15546                         ? removedChildPackages.size() : 0;
15547                 for (int i = 0; i < childCount; i++) {
15548                     PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15549                     if (childInfo.isRemovedPackageSystemUpdate) {
15550                         childInfo.sendSystemPackageUpdatedBroadcastsInternal();
15551                     }
15552                 }
15553             }
15554         }
15555 
sendSystemPackageAppearedBroadcasts()15556         void sendSystemPackageAppearedBroadcasts() {
15557             final int packageCount = (appearedChildPackages != null)
15558                     ? appearedChildPackages.size() : 0;
15559             for (int i = 0; i < packageCount; i++) {
15560                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
15561                 for (int userId : installedInfo.newUsers) {
15562                     sendPackageAddedForUser(installedInfo.name, true,
15563                             UserHandle.getAppId(installedInfo.uid), userId);
15564                 }
15565             }
15566         }
15567 
sendSystemPackageUpdatedBroadcastsInternal()15568         private void sendSystemPackageUpdatedBroadcastsInternal() {
15569             Bundle extras = new Bundle(2);
15570             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
15571             extras.putBoolean(Intent.EXTRA_REPLACING, true);
15572             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
15573                     extras, 0, null, null, null);
15574             sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
15575                     extras, 0, null, null, null);
15576             sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
15577                     null, 0, removedPackage, null, null);
15578         }
15579 
sendPackageRemovedBroadcastInternal(boolean killApp)15580         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
15581             Bundle extras = new Bundle(2);
15582             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
15583             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
15584             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
15585             if (isUpdate || isRemovedPackageSystemUpdate) {
15586                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
15587             }
15588             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
15589             if (removedPackage != null) {
15590                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
15591                         extras, 0, null, null, removedUsers);
15592                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
15593                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
15594                             removedPackage, extras, 0, null, null, removedUsers);
15595                 }
15596             }
15597             if (removedAppId >= 0) {
15598                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
15599                         removedUsers);
15600             }
15601         }
15602     }
15603 
15604     /*
15605      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
15606      * flag is not set, the data directory is removed as well.
15607      * make sure this flag is set for partially installed apps. If not its meaningless to
15608      * delete a partially installed application.
15609      */
removePackageDataLIF(PackageSetting ps, int[] allUserHandles, PackageRemovedInfo outInfo, int flags, boolean writeSettings)15610     private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
15611             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
15612         String packageName = ps.name;
15613         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
15614         // Retrieve object to delete permissions for shared user later on
15615         final PackageParser.Package deletedPkg;
15616         final PackageSetting deletedPs;
15617         // reader
15618         synchronized (mPackages) {
15619             deletedPkg = mPackages.get(packageName);
15620             deletedPs = mSettings.mPackages.get(packageName);
15621             if (outInfo != null) {
15622                 outInfo.removedPackage = packageName;
15623                 outInfo.removedUsers = deletedPs != null
15624                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
15625                         : null;
15626             }
15627         }
15628 
15629         removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
15630 
15631         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
15632             final PackageParser.Package resolvedPkg;
15633             if (deletedPkg != null) {
15634                 resolvedPkg = deletedPkg;
15635             } else {
15636                 // We don't have a parsed package when it lives on an ejected
15637                 // adopted storage device, so fake something together
15638                 resolvedPkg = new PackageParser.Package(ps.name);
15639                 resolvedPkg.setVolumeUuid(ps.volumeUuid);
15640             }
15641             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
15642                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
15643             destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
15644             if (outInfo != null) {
15645                 outInfo.dataRemoved = true;
15646             }
15647             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
15648         }
15649 
15650         // writer
15651         synchronized (mPackages) {
15652             if (deletedPs != null) {
15653                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
15654                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
15655                     clearDefaultBrowserIfNeeded(packageName);
15656                     if (outInfo != null) {
15657                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
15658                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
15659                     }
15660                     updatePermissionsLPw(deletedPs.name, null, 0);
15661                     if (deletedPs.sharedUser != null) {
15662                         // Remove permissions associated with package. Since runtime
15663                         // permissions are per user we have to kill the removed package
15664                         // or packages running under the shared user of the removed
15665                         // package if revoking the permissions requested only by the removed
15666                         // package is successful and this causes a change in gids.
15667                         for (int userId : UserManagerService.getInstance().getUserIds()) {
15668                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
15669                                     userId);
15670                             if (userIdToKill == UserHandle.USER_ALL
15671                                     || userIdToKill >= UserHandle.USER_SYSTEM) {
15672                                 // If gids changed for this user, kill all affected packages.
15673                                 mHandler.post(new Runnable() {
15674                                     @Override
15675                                     public void run() {
15676                                         // This has to happen with no lock held.
15677                                         killApplication(deletedPs.name, deletedPs.appId,
15678                                                 KILL_APP_REASON_GIDS_CHANGED);
15679                                     }
15680                                 });
15681                                 break;
15682                             }
15683                         }
15684                     }
15685                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
15686                 }
15687                 // make sure to preserve per-user disabled state if this removal was just
15688                 // a downgrade of a system app to the factory package
15689                 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
15690                     if (DEBUG_REMOVE) {
15691                         Slog.d(TAG, "Propagating install state across downgrade");
15692                     }
15693                     for (int userId : allUserHandles) {
15694                         final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
15695                         if (DEBUG_REMOVE) {
15696                             Slog.d(TAG, "    user " + userId + " => " + installed);
15697                         }
15698                         ps.setInstalled(installed, userId);
15699                     }
15700                 }
15701             }
15702             // can downgrade to reader
15703             if (writeSettings) {
15704                 // Save settings now
15705                 mSettings.writeLPr();
15706             }
15707         }
15708         if (outInfo != null) {
15709             // A user ID was deleted here. Go through all users and remove it
15710             // from KeyStore.
15711             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
15712         }
15713     }
15714 
locationIsPrivileged(File path)15715     static boolean locationIsPrivileged(File path) {
15716         try {
15717             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
15718                     .getCanonicalPath();
15719             return path.getCanonicalPath().startsWith(privilegedAppDir);
15720         } catch (IOException e) {
15721             Slog.e(TAG, "Unable to access code path " + path);
15722         }
15723         return false;
15724     }
15725 
15726     /*
15727      * Tries to delete system package.
15728      */
deleteSystemPackageLIF(PackageParser.Package deletedPkg, PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings)15729     private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
15730             PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
15731             boolean writeSettings) {
15732         if (deletedPs.parentPackageName != null) {
15733             Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
15734             return false;
15735         }
15736 
15737         final boolean applyUserRestrictions
15738                 = (allUserHandles != null) && (outInfo.origUsers != null);
15739         final PackageSetting disabledPs;
15740         // Confirm if the system package has been updated
15741         // An updated system app can be deleted. This will also have to restore
15742         // the system pkg from system partition
15743         // reader
15744         synchronized (mPackages) {
15745             disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
15746         }
15747 
15748         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
15749                 + " disabledPs=" + disabledPs);
15750 
15751         if (disabledPs == null) {
15752             Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
15753             return false;
15754         } else if (DEBUG_REMOVE) {
15755             Slog.d(TAG, "Deleting system pkg from data partition");
15756         }
15757 
15758         if (DEBUG_REMOVE) {
15759             if (applyUserRestrictions) {
15760                 Slog.d(TAG, "Remembering install states:");
15761                 for (int userId : allUserHandles) {
15762                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
15763                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
15764                 }
15765             }
15766         }
15767 
15768         // Delete the updated package
15769         outInfo.isRemovedPackageSystemUpdate = true;
15770         if (outInfo.removedChildPackages != null) {
15771             final int childCount = (deletedPs.childPackageNames != null)
15772                     ? deletedPs.childPackageNames.size() : 0;
15773             for (int i = 0; i < childCount; i++) {
15774                 String childPackageName = deletedPs.childPackageNames.get(i);
15775                 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
15776                         .contains(childPackageName)) {
15777                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
15778                             childPackageName);
15779                     if (childInfo != null) {
15780                         childInfo.isRemovedPackageSystemUpdate = true;
15781                     }
15782                 }
15783             }
15784         }
15785 
15786         if (disabledPs.versionCode < deletedPs.versionCode) {
15787             // Delete data for downgrades
15788             flags &= ~PackageManager.DELETE_KEEP_DATA;
15789         } else {
15790             // Preserve data by setting flag
15791             flags |= PackageManager.DELETE_KEEP_DATA;
15792         }
15793 
15794         boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
15795                 outInfo, writeSettings, disabledPs.pkg);
15796         if (!ret) {
15797             return false;
15798         }
15799 
15800         // writer
15801         synchronized (mPackages) {
15802             // Reinstate the old system package
15803             enableSystemPackageLPw(disabledPs.pkg);
15804             // Remove any native libraries from the upgraded package.
15805             removeNativeBinariesLI(deletedPs);
15806         }
15807 
15808         // Install the system package
15809         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
15810         int parseFlags = mDefParseFlags
15811                 | PackageParser.PARSE_MUST_BE_APK
15812                 | PackageParser.PARSE_IS_SYSTEM
15813                 | PackageParser.PARSE_IS_SYSTEM_DIR;
15814         if (locationIsPrivileged(disabledPs.codePath)) {
15815             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
15816         }
15817 
15818         final PackageParser.Package newPkg;
15819         try {
15820             newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
15821         } catch (PackageManagerException e) {
15822             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
15823                     + e.getMessage());
15824             return false;
15825         }
15826         try {
15827             // update shared libraries for the newly re-installed system package
15828             updateSharedLibrariesLPw(newPkg, null);
15829         } catch (PackageManagerException e) {
15830             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
15831         }
15832 
15833         prepareAppDataAfterInstallLIF(newPkg);
15834 
15835         // writer
15836         synchronized (mPackages) {
15837             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
15838 
15839             // Propagate the permissions state as we do not want to drop on the floor
15840             // runtime permissions. The update permissions method below will take
15841             // care of removing obsolete permissions and grant install permissions.
15842             ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
15843             updatePermissionsLPw(newPkg.packageName, newPkg,
15844                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
15845 
15846             if (applyUserRestrictions) {
15847                 if (DEBUG_REMOVE) {
15848                     Slog.d(TAG, "Propagating install state across reinstall");
15849                 }
15850                 for (int userId : allUserHandles) {
15851                     final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
15852                     if (DEBUG_REMOVE) {
15853                         Slog.d(TAG, "    user " + userId + " => " + installed);
15854                     }
15855                     ps.setInstalled(installed, userId);
15856 
15857                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
15858                 }
15859                 // Regardless of writeSettings we need to ensure that this restriction
15860                 // state propagation is persisted
15861                 mSettings.writeAllUsersPackageRestrictionsLPr();
15862             }
15863             // can downgrade to reader here
15864             if (writeSettings) {
15865                 mSettings.writeLPr();
15866             }
15867         }
15868         return true;
15869     }
15870 
deleteInstalledPackageLIF(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, PackageRemovedInfo outInfo, boolean writeSettings, PackageParser.Package replacingPackage)15871     private boolean deleteInstalledPackageLIF(PackageSetting ps,
15872             boolean deleteCodeAndResources, int flags, int[] allUserHandles,
15873             PackageRemovedInfo outInfo, boolean writeSettings,
15874             PackageParser.Package replacingPackage) {
15875         synchronized (mPackages) {
15876             if (outInfo != null) {
15877                 outInfo.uid = ps.appId;
15878             }
15879 
15880             if (outInfo != null && outInfo.removedChildPackages != null) {
15881                 final int childCount = (ps.childPackageNames != null)
15882                         ? ps.childPackageNames.size() : 0;
15883                 for (int i = 0; i < childCount; i++) {
15884                     String childPackageName = ps.childPackageNames.get(i);
15885                     PackageSetting childPs = mSettings.mPackages.get(childPackageName);
15886                     if (childPs == null) {
15887                         return false;
15888                     }
15889                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
15890                             childPackageName);
15891                     if (childInfo != null) {
15892                         childInfo.uid = childPs.appId;
15893                     }
15894                 }
15895             }
15896         }
15897 
15898         // Delete package data from internal structures and also remove data if flag is set
15899         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
15900 
15901         // Delete the child packages data
15902         final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
15903         for (int i = 0; i < childCount; i++) {
15904             PackageSetting childPs;
15905             synchronized (mPackages) {
15906                 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
15907             }
15908             if (childPs != null) {
15909                 PackageRemovedInfo childOutInfo = (outInfo != null
15910                         && outInfo.removedChildPackages != null)
15911                         ? outInfo.removedChildPackages.get(childPs.name) : null;
15912                 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
15913                         && (replacingPackage != null
15914                         && !replacingPackage.hasChildPackage(childPs.name))
15915                         ? flags & ~DELETE_KEEP_DATA : flags;
15916                 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
15917                         deleteFlags, writeSettings);
15918             }
15919         }
15920 
15921         // Delete application code and resources only for parent packages
15922         if (ps.parentPackageName == null) {
15923             if (deleteCodeAndResources && (outInfo != null)) {
15924                 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
15925                         ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
15926                 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
15927             }
15928         }
15929 
15930         return true;
15931     }
15932 
15933     @Override
setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)15934     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
15935             int userId) {
15936         mContext.enforceCallingOrSelfPermission(
15937                 android.Manifest.permission.DELETE_PACKAGES, null);
15938         synchronized (mPackages) {
15939             PackageSetting ps = mSettings.mPackages.get(packageName);
15940             if (ps == null) {
15941                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
15942                 return false;
15943             }
15944             if (!ps.getInstalled(userId)) {
15945                 // Can't block uninstall for an app that is not installed or enabled.
15946                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
15947                 return false;
15948             }
15949             ps.setBlockUninstall(blockUninstall, userId);
15950             mSettings.writePackageRestrictionsLPr(userId);
15951         }
15952         return true;
15953     }
15954 
15955     @Override
getBlockUninstallForUser(String packageName, int userId)15956     public boolean getBlockUninstallForUser(String packageName, int userId) {
15957         synchronized (mPackages) {
15958             PackageSetting ps = mSettings.mPackages.get(packageName);
15959             if (ps == null) {
15960                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
15961                 return false;
15962             }
15963             return ps.getBlockUninstall(userId);
15964         }
15965     }
15966 
15967     @Override
setRequiredForSystemUser(String packageName, boolean systemUserApp)15968     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
15969         int callingUid = Binder.getCallingUid();
15970         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
15971             throw new SecurityException(
15972                     "setRequiredForSystemUser can only be run by the system or root");
15973         }
15974         synchronized (mPackages) {
15975             PackageSetting ps = mSettings.mPackages.get(packageName);
15976             if (ps == null) {
15977                 Log.w(TAG, "Package doesn't exist: " + packageName);
15978                 return false;
15979             }
15980             if (systemUserApp) {
15981                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
15982             } else {
15983                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
15984             }
15985             mSettings.writeLPr();
15986         }
15987         return true;
15988     }
15989 
15990     /*
15991      * This method handles package deletion in general
15992      */
deletePackageLIF(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings, PackageParser.Package replacingPackage)15993     private boolean deletePackageLIF(String packageName, UserHandle user,
15994             boolean deleteCodeAndResources, int[] allUserHandles, int flags,
15995             PackageRemovedInfo outInfo, boolean writeSettings,
15996             PackageParser.Package replacingPackage) {
15997         if (packageName == null) {
15998             Slog.w(TAG, "Attempt to delete null packageName.");
15999             return false;
16000         }
16001 
16002         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
16003 
16004         PackageSetting ps;
16005 
16006         synchronized (mPackages) {
16007             ps = mSettings.mPackages.get(packageName);
16008             if (ps == null) {
16009                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16010                 return false;
16011             }
16012 
16013             if (ps.parentPackageName != null && (!isSystemApp(ps)
16014                     || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
16015                 if (DEBUG_REMOVE) {
16016                     Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
16017                             + ((user == null) ? UserHandle.USER_ALL : user));
16018                 }
16019                 final int removedUserId = (user != null) ? user.getIdentifier()
16020                         : UserHandle.USER_ALL;
16021                 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
16022                     return false;
16023                 }
16024                 markPackageUninstalledForUserLPw(ps, user);
16025                 scheduleWritePackageRestrictionsLocked(user);
16026                 return true;
16027             }
16028         }
16029 
16030         if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
16031                 && user.getIdentifier() != UserHandle.USER_ALL)) {
16032             // The caller is asking that the package only be deleted for a single
16033             // user.  To do this, we just mark its uninstalled state and delete
16034             // its data. If this is a system app, we only allow this to happen if
16035             // they have set the special DELETE_SYSTEM_APP which requests different
16036             // semantics than normal for uninstalling system apps.
16037             markPackageUninstalledForUserLPw(ps, user);
16038 
16039             if (!isSystemApp(ps)) {
16040                 // Do not uninstall the APK if an app should be cached
16041                 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
16042                 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
16043                     // Other user still have this package installed, so all
16044                     // we need to do is clear this user's data and save that
16045                     // it is uninstalled.
16046                     if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
16047                     if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16048                         return false;
16049                     }
16050                     scheduleWritePackageRestrictionsLocked(user);
16051                     return true;
16052                 } else {
16053                     // We need to set it back to 'installed' so the uninstall
16054                     // broadcasts will be sent correctly.
16055                     if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
16056                     ps.setInstalled(true, user.getIdentifier());
16057                 }
16058             } else {
16059                 // This is a system app, so we assume that the
16060                 // other users still have this package installed, so all
16061                 // we need to do is clear this user's data and save that
16062                 // it is uninstalled.
16063                 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
16064                 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16065                     return false;
16066                 }
16067                 scheduleWritePackageRestrictionsLocked(user);
16068                 return true;
16069             }
16070         }
16071 
16072         // If we are deleting a composite package for all users, keep track
16073         // of result for each child.
16074         if (ps.childPackageNames != null && outInfo != null) {
16075             synchronized (mPackages) {
16076                 final int childCount = ps.childPackageNames.size();
16077                 outInfo.removedChildPackages = new ArrayMap<>(childCount);
16078                 for (int i = 0; i < childCount; i++) {
16079                     String childPackageName = ps.childPackageNames.get(i);
16080                     PackageRemovedInfo childInfo = new PackageRemovedInfo();
16081                     childInfo.removedPackage = childPackageName;
16082                     outInfo.removedChildPackages.put(childPackageName, childInfo);
16083                     PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16084                     if (childPs != null) {
16085                         childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
16086                     }
16087                 }
16088             }
16089         }
16090 
16091         boolean ret = false;
16092         if (isSystemApp(ps)) {
16093             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
16094             // When an updated system application is deleted we delete the existing resources
16095             // as well and fall back to existing code in system partition
16096             ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
16097         } else {
16098             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
16099             ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
16100                     outInfo, writeSettings, replacingPackage);
16101         }
16102 
16103         // Take a note whether we deleted the package for all users
16104         if (outInfo != null) {
16105             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16106             if (outInfo.removedChildPackages != null) {
16107                 synchronized (mPackages) {
16108                     final int childCount = outInfo.removedChildPackages.size();
16109                     for (int i = 0; i < childCount; i++) {
16110                         PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
16111                         if (childInfo != null) {
16112                             childInfo.removedForAllUsers = mPackages.get(
16113                                     childInfo.removedPackage) == null;
16114                         }
16115                     }
16116                 }
16117             }
16118             // If we uninstalled an update to a system app there may be some
16119             // child packages that appeared as they are declared in the system
16120             // app but were not declared in the update.
16121             if (isSystemApp(ps)) {
16122                 synchronized (mPackages) {
16123                     PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name);
16124                     final int childCount = (updatedPs.childPackageNames != null)
16125                             ? updatedPs.childPackageNames.size() : 0;
16126                     for (int i = 0; i < childCount; i++) {
16127                         String childPackageName = updatedPs.childPackageNames.get(i);
16128                         if (outInfo.removedChildPackages == null
16129                                 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
16130                             PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16131                             if (childPs == null) {
16132                                 continue;
16133                             }
16134                             PackageInstalledInfo installRes = new PackageInstalledInfo();
16135                             installRes.name = childPackageName;
16136                             installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
16137                             installRes.pkg = mPackages.get(childPackageName);
16138                             installRes.uid = childPs.pkg.applicationInfo.uid;
16139                             if (outInfo.appearedChildPackages == null) {
16140                                 outInfo.appearedChildPackages = new ArrayMap<>();
16141                             }
16142                             outInfo.appearedChildPackages.put(childPackageName, installRes);
16143                         }
16144                     }
16145                 }
16146             }
16147         }
16148 
16149         return ret;
16150     }
16151 
markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user)16152     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
16153         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
16154                 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
16155         for (int nextUserId : userIds) {
16156             if (DEBUG_REMOVE) {
16157                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
16158             }
16159             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
16160                     false /*installed*/, true /*stopped*/, true /*notLaunched*/,
16161                     false /*hidden*/, false /*suspended*/, null, null, null,
16162                     false /*blockUninstall*/,
16163                     ps.readUserState(nextUserId).domainVerificationStatus, 0);
16164         }
16165     }
16166 
clearPackageStateForUserLIF(PackageSetting ps, int userId, PackageRemovedInfo outInfo)16167     private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
16168             PackageRemovedInfo outInfo) {
16169         final PackageParser.Package pkg;
16170         synchronized (mPackages) {
16171             pkg = mPackages.get(ps.name);
16172         }
16173 
16174         final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
16175                 : new int[] {userId};
16176         for (int nextUserId : userIds) {
16177             if (DEBUG_REMOVE) {
16178                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
16179                         + nextUserId);
16180             }
16181 
16182             destroyAppDataLIF(pkg, userId,
16183                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16184             destroyAppProfilesLIF(pkg, userId);
16185             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
16186             schedulePackageCleaning(ps.name, nextUserId, false);
16187             synchronized (mPackages) {
16188                 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
16189                     scheduleWritePackageRestrictionsLocked(nextUserId);
16190                 }
16191                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
16192             }
16193         }
16194 
16195         if (outInfo != null) {
16196             outInfo.removedPackage = ps.name;
16197             outInfo.removedAppId = ps.appId;
16198             outInfo.removedUsers = userIds;
16199         }
16200 
16201         return true;
16202     }
16203 
16204     private final class ClearStorageConnection implements ServiceConnection {
16205         IMediaContainerService mContainerService;
16206 
16207         @Override
onServiceConnected(ComponentName name, IBinder service)16208         public void onServiceConnected(ComponentName name, IBinder service) {
16209             synchronized (this) {
16210                 mContainerService = IMediaContainerService.Stub.asInterface(service);
16211                 notifyAll();
16212             }
16213         }
16214 
16215         @Override
onServiceDisconnected(ComponentName name)16216         public void onServiceDisconnected(ComponentName name) {
16217         }
16218     }
16219 
clearExternalStorageDataSync(String packageName, int userId, boolean allData)16220     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
16221         if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
16222 
16223         final boolean mounted;
16224         if (Environment.isExternalStorageEmulated()) {
16225             mounted = true;
16226         } else {
16227             final String status = Environment.getExternalStorageState();
16228 
16229             mounted = status.equals(Environment.MEDIA_MOUNTED)
16230                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
16231         }
16232 
16233         if (!mounted) {
16234             return;
16235         }
16236 
16237         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
16238         int[] users;
16239         if (userId == UserHandle.USER_ALL) {
16240             users = sUserManager.getUserIds();
16241         } else {
16242             users = new int[] { userId };
16243         }
16244         final ClearStorageConnection conn = new ClearStorageConnection();
16245         if (mContext.bindServiceAsUser(
16246                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
16247             try {
16248                 for (int curUser : users) {
16249                     long timeout = SystemClock.uptimeMillis() + 5000;
16250                     synchronized (conn) {
16251                         long now;
16252                         while (conn.mContainerService == null &&
16253                                 (now = SystemClock.uptimeMillis()) < timeout) {
16254                             try {
16255                                 conn.wait(timeout - now);
16256                             } catch (InterruptedException e) {
16257                             }
16258                         }
16259                     }
16260                     if (conn.mContainerService == null) {
16261                         return;
16262                     }
16263 
16264                     final UserEnvironment userEnv = new UserEnvironment(curUser);
16265                     clearDirectory(conn.mContainerService,
16266                             userEnv.buildExternalStorageAppCacheDirs(packageName));
16267                     if (allData) {
16268                         clearDirectory(conn.mContainerService,
16269                                 userEnv.buildExternalStorageAppDataDirs(packageName));
16270                         clearDirectory(conn.mContainerService,
16271                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
16272                     }
16273                 }
16274             } finally {
16275                 mContext.unbindService(conn);
16276             }
16277         }
16278     }
16279 
16280     @Override
clearApplicationProfileData(String packageName)16281     public void clearApplicationProfileData(String packageName) {
16282         enforceSystemOrRoot("Only the system can clear all profile data");
16283 
16284         final PackageParser.Package pkg;
16285         synchronized (mPackages) {
16286             pkg = mPackages.get(packageName);
16287         }
16288 
16289         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
16290             synchronized (mInstallLock) {
16291                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
16292                 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL,
16293                         true /* removeBaseMarker */);
16294             }
16295         }
16296     }
16297 
16298     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)16299     public void clearApplicationUserData(final String packageName,
16300             final IPackageDataObserver observer, final int userId) {
16301         mContext.enforceCallingOrSelfPermission(
16302                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
16303 
16304         enforceCrossUserPermission(Binder.getCallingUid(), userId,
16305                 true /* requireFullPermission */, false /* checkShell */, "clear application data");
16306 
16307         if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
16308             throw new SecurityException("Cannot clear data for a protected package: "
16309                     + packageName);
16310         }
16311         // Queue up an async operation since the package deletion may take a little while.
16312         mHandler.post(new Runnable() {
16313             public void run() {
16314                 mHandler.removeCallbacks(this);
16315                 final boolean succeeded;
16316                 try (PackageFreezer freezer = freezePackage(packageName,
16317                         "clearApplicationUserData")) {
16318                     synchronized (mInstallLock) {
16319                         succeeded = clearApplicationUserDataLIF(packageName, userId);
16320                     }
16321                     clearExternalStorageDataSync(packageName, userId, true);
16322                 }
16323                 if (succeeded) {
16324                     // invoke DeviceStorageMonitor's update method to clear any notifications
16325                     DeviceStorageMonitorInternal dsm = LocalServices
16326                             .getService(DeviceStorageMonitorInternal.class);
16327                     if (dsm != null) {
16328                         dsm.checkMemory();
16329                     }
16330                 }
16331                 if(observer != null) {
16332                     try {
16333                         observer.onRemoveCompleted(packageName, succeeded);
16334                     } catch (RemoteException e) {
16335                         Log.i(TAG, "Observer no longer exists.");
16336                     }
16337                 } //end if observer
16338             } //end run
16339         });
16340     }
16341 
clearApplicationUserDataLIF(String packageName, int userId)16342     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
16343         if (packageName == null) {
16344             Slog.w(TAG, "Attempt to delete null packageName.");
16345             return false;
16346         }
16347 
16348         // Try finding details about the requested package
16349         PackageParser.Package pkg;
16350         synchronized (mPackages) {
16351             pkg = mPackages.get(packageName);
16352             if (pkg == null) {
16353                 final PackageSetting ps = mSettings.mPackages.get(packageName);
16354                 if (ps != null) {
16355                     pkg = ps.pkg;
16356                 }
16357             }
16358 
16359             if (pkg == null) {
16360                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16361                 return false;
16362             }
16363 
16364             PackageSetting ps = (PackageSetting) pkg.mExtras;
16365             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16366         }
16367 
16368         clearAppDataLIF(pkg, userId,
16369                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16370 
16371         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16372         removeKeystoreDataIfNeeded(userId, appId);
16373 
16374         UserManagerInternal umInternal = getUserManagerInternal();
16375         final int flags;
16376         if (umInternal.isUserUnlockingOrUnlocked(userId)) {
16377             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
16378         } else if (umInternal.isUserRunning(userId)) {
16379             flags = StorageManager.FLAG_STORAGE_DE;
16380         } else {
16381             flags = 0;
16382         }
16383         prepareAppDataContentsLIF(pkg, userId, flags);
16384 
16385         return true;
16386     }
16387 
16388     /**
16389      * Reverts user permission state changes (permissions and flags) in
16390      * all packages for a given user.
16391      *
16392      * @param userId The device user for which to do a reset.
16393      */
resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId)16394     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
16395         final int packageCount = mPackages.size();
16396         for (int i = 0; i < packageCount; i++) {
16397             PackageParser.Package pkg = mPackages.valueAt(i);
16398             PackageSetting ps = (PackageSetting) pkg.mExtras;
16399             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16400         }
16401     }
16402 
resetNetworkPolicies(int userId)16403     private void resetNetworkPolicies(int userId) {
16404         LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
16405     }
16406 
16407     /**
16408      * Reverts user permission state changes (permissions and flags).
16409      *
16410      * @param ps The package for which to reset.
16411      * @param userId The device user for which to do a reset.
16412      */
resetUserChangesToRuntimePermissionsAndFlagsLPw( final PackageSetting ps, final int userId)16413     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
16414             final PackageSetting ps, final int userId) {
16415         if (ps.pkg == null) {
16416             return;
16417         }
16418 
16419         // These are flags that can change base on user actions.
16420         final int userSettableMask = FLAG_PERMISSION_USER_SET
16421                 | FLAG_PERMISSION_USER_FIXED
16422                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
16423                 | FLAG_PERMISSION_REVIEW_REQUIRED;
16424 
16425         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
16426                 | FLAG_PERMISSION_POLICY_FIXED;
16427 
16428         boolean writeInstallPermissions = false;
16429         boolean writeRuntimePermissions = false;
16430 
16431         final int permissionCount = ps.pkg.requestedPermissions.size();
16432         for (int i = 0; i < permissionCount; i++) {
16433             String permission = ps.pkg.requestedPermissions.get(i);
16434 
16435             BasePermission bp = mSettings.mPermissions.get(permission);
16436             if (bp == null) {
16437                 continue;
16438             }
16439 
16440             // If shared user we just reset the state to which only this app contributed.
16441             if (ps.sharedUser != null) {
16442                 boolean used = false;
16443                 final int packageCount = ps.sharedUser.packages.size();
16444                 for (int j = 0; j < packageCount; j++) {
16445                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
16446                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
16447                             && pkg.pkg.requestedPermissions.contains(permission)) {
16448                         used = true;
16449                         break;
16450                     }
16451                 }
16452                 if (used) {
16453                     continue;
16454                 }
16455             }
16456 
16457             PermissionsState permissionsState = ps.getPermissionsState();
16458 
16459             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
16460 
16461             // Always clear the user settable flags.
16462             final boolean hasInstallState = permissionsState.getInstallPermissionState(
16463                     bp.name) != null;
16464             // If permission review is enabled and this is a legacy app, mark the
16465             // permission as requiring a review as this is the initial state.
16466             int flags = 0;
16467             if (Build.PERMISSIONS_REVIEW_REQUIRED
16468                     && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
16469                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
16470             }
16471             if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
16472                 if (hasInstallState) {
16473                     writeInstallPermissions = true;
16474                 } else {
16475                     writeRuntimePermissions = true;
16476                 }
16477             }
16478 
16479             // Below is only runtime permission handling.
16480             if (!bp.isRuntime()) {
16481                 continue;
16482             }
16483 
16484             // Never clobber system or policy.
16485             if ((oldFlags & policyOrSystemFlags) != 0) {
16486                 continue;
16487             }
16488 
16489             // If this permission was granted by default, make sure it is.
16490             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
16491                 if (permissionsState.grantRuntimePermission(bp, userId)
16492                         != PERMISSION_OPERATION_FAILURE) {
16493                     writeRuntimePermissions = true;
16494                 }
16495             // If permission review is enabled the permissions for a legacy apps
16496             // are represented as constantly granted runtime ones, so don't revoke.
16497             } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
16498                 // Otherwise, reset the permission.
16499                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
16500                 switch (revokeResult) {
16501                     case PERMISSION_OPERATION_SUCCESS:
16502                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
16503                         writeRuntimePermissions = true;
16504                         final int appId = ps.appId;
16505                         mHandler.post(new Runnable() {
16506                             @Override
16507                             public void run() {
16508                                 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
16509                             }
16510                         });
16511                     } break;
16512                 }
16513             }
16514         }
16515 
16516         // Synchronously write as we are taking permissions away.
16517         if (writeRuntimePermissions) {
16518             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
16519         }
16520 
16521         // Synchronously write as we are taking permissions away.
16522         if (writeInstallPermissions) {
16523             mSettings.writeLPr();
16524         }
16525     }
16526 
16527     /**
16528      * Remove entries from the keystore daemon. Will only remove it if the
16529      * {@code appId} is valid.
16530      */
removeKeystoreDataIfNeeded(int userId, int appId)16531     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
16532         if (appId < 0) {
16533             return;
16534         }
16535 
16536         final KeyStore keyStore = KeyStore.getInstance();
16537         if (keyStore != null) {
16538             if (userId == UserHandle.USER_ALL) {
16539                 for (final int individual : sUserManager.getUserIds()) {
16540                     keyStore.clearUid(UserHandle.getUid(individual, appId));
16541                 }
16542             } else {
16543                 keyStore.clearUid(UserHandle.getUid(userId, appId));
16544             }
16545         } else {
16546             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
16547         }
16548     }
16549 
16550     @Override
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)16551     public void deleteApplicationCacheFiles(final String packageName,
16552             final IPackageDataObserver observer) {
16553         final int userId = UserHandle.getCallingUserId();
16554         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
16555     }
16556 
16557     @Override
deleteApplicationCacheFilesAsUser(final String packageName, final int userId, final IPackageDataObserver observer)16558     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
16559             final IPackageDataObserver observer) {
16560         mContext.enforceCallingOrSelfPermission(
16561                 android.Manifest.permission.DELETE_CACHE_FILES, null);
16562         enforceCrossUserPermission(Binder.getCallingUid(), userId,
16563                 /* requireFullPermission= */ true, /* checkShell= */ false,
16564                 "delete application cache files");
16565 
16566         final PackageParser.Package pkg;
16567         synchronized (mPackages) {
16568             pkg = mPackages.get(packageName);
16569         }
16570 
16571         // Queue up an async operation since the package deletion may take a little while.
16572         mHandler.post(new Runnable() {
16573             public void run() {
16574                 synchronized (mInstallLock) {
16575                     final int flags = StorageManager.FLAG_STORAGE_DE
16576                             | StorageManager.FLAG_STORAGE_CE;
16577                     // We're only clearing cache files, so we don't care if the
16578                     // app is unfrozen and still able to run
16579                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
16580                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16581                 }
16582                 clearExternalStorageDataSync(packageName, userId, false);
16583                 if (observer != null) {
16584                     try {
16585                         observer.onRemoveCompleted(packageName, true);
16586                     } catch (RemoteException e) {
16587                         Log.i(TAG, "Observer no longer exists.");
16588                     }
16589                 }
16590             }
16591         });
16592     }
16593 
16594     @Override
getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)16595     public void getPackageSizeInfo(final String packageName, int userHandle,
16596             final IPackageStatsObserver observer) {
16597         mContext.enforceCallingOrSelfPermission(
16598                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
16599         if (packageName == null) {
16600             throw new IllegalArgumentException("Attempt to get size of null packageName");
16601         }
16602 
16603         PackageStats stats = new PackageStats(packageName, userHandle);
16604 
16605         /*
16606          * Queue up an async operation since the package measurement may take a
16607          * little while.
16608          */
16609         Message msg = mHandler.obtainMessage(INIT_COPY);
16610         msg.obj = new MeasureParams(stats, observer);
16611         mHandler.sendMessage(msg);
16612     }
16613 
getPackageSizeInfoLI(String packageName, int userId, PackageStats stats)16614     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
16615         final PackageSetting ps;
16616         synchronized (mPackages) {
16617             ps = mSettings.mPackages.get(packageName);
16618             if (ps == null) {
16619                 Slog.w(TAG, "Failed to find settings for " + packageName);
16620                 return false;
16621             }
16622         }
16623         try {
16624             mInstaller.getAppSize(ps.volumeUuid, packageName, userId,
16625                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE,
16626                     ps.getCeDataInode(userId), ps.codePathString, stats);
16627         } catch (InstallerException e) {
16628             Slog.w(TAG, String.valueOf(e));
16629             return false;
16630         }
16631 
16632         // For now, ignore code size of packages on system partition
16633         if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
16634             stats.codeSize = 0;
16635         }
16636 
16637         return true;
16638     }
16639 
getUidTargetSdkVersionLockedLPr(int uid)16640     private int getUidTargetSdkVersionLockedLPr(int uid) {
16641         Object obj = mSettings.getUserIdLPr(uid);
16642         if (obj instanceof SharedUserSetting) {
16643             final SharedUserSetting sus = (SharedUserSetting) obj;
16644             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
16645             final Iterator<PackageSetting> it = sus.packages.iterator();
16646             while (it.hasNext()) {
16647                 final PackageSetting ps = it.next();
16648                 if (ps.pkg != null) {
16649                     int v = ps.pkg.applicationInfo.targetSdkVersion;
16650                     if (v < vers) vers = v;
16651                 }
16652             }
16653             return vers;
16654         } else if (obj instanceof PackageSetting) {
16655             final PackageSetting ps = (PackageSetting) obj;
16656             if (ps.pkg != null) {
16657                 return ps.pkg.applicationInfo.targetSdkVersion;
16658             }
16659         }
16660         return Build.VERSION_CODES.CUR_DEVELOPMENT;
16661     }
16662 
16663     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)16664     public void addPreferredActivity(IntentFilter filter, int match,
16665             ComponentName[] set, ComponentName activity, int userId) {
16666         addPreferredActivityInternal(filter, match, set, activity, true, userId,
16667                 "Adding preferred");
16668     }
16669 
addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname)16670     private void addPreferredActivityInternal(IntentFilter filter, int match,
16671             ComponentName[] set, ComponentName activity, boolean always, int userId,
16672             String opname) {
16673         // writer
16674         int callingUid = Binder.getCallingUid();
16675         enforceCrossUserPermission(callingUid, userId,
16676                 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
16677         if (filter.countActions() == 0) {
16678             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
16679             return;
16680         }
16681         synchronized (mPackages) {
16682             if (mContext.checkCallingOrSelfPermission(
16683                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
16684                     != PackageManager.PERMISSION_GRANTED) {
16685                 if (getUidTargetSdkVersionLockedLPr(callingUid)
16686                         < Build.VERSION_CODES.FROYO) {
16687                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
16688                             + callingUid);
16689                     return;
16690                 }
16691                 mContext.enforceCallingOrSelfPermission(
16692                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
16693             }
16694 
16695             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
16696             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
16697                     + userId + ":");
16698             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
16699             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
16700             scheduleWritePackageRestrictionsLocked(userId);
16701             postPreferredActivityChangedBroadcast(userId);
16702         }
16703     }
16704 
postPreferredActivityChangedBroadcast(int userId)16705     private void postPreferredActivityChangedBroadcast(int userId) {
16706         mHandler.post(() -> {
16707             final IActivityManager am = ActivityManagerNative.getDefault();
16708             if (am == null) {
16709                 return;
16710             }
16711 
16712             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
16713             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16714             try {
16715                 am.broadcastIntent(null, intent, null, null,
16716                         0, null, null, null, android.app.AppOpsManager.OP_NONE,
16717                         null, false, false, userId);
16718             } catch (RemoteException e) {
16719             }
16720         });
16721     }
16722 
16723     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)16724     public void replacePreferredActivity(IntentFilter filter, int match,
16725             ComponentName[] set, ComponentName activity, int userId) {
16726         if (filter.countActions() != 1) {
16727             throw new IllegalArgumentException(
16728                     "replacePreferredActivity expects filter to have only 1 action.");
16729         }
16730         if (filter.countDataAuthorities() != 0
16731                 || filter.countDataPaths() != 0
16732                 || filter.countDataSchemes() > 1
16733                 || filter.countDataTypes() != 0) {
16734             throw new IllegalArgumentException(
16735                     "replacePreferredActivity expects filter to have no data authorities, " +
16736                     "paths, or types; and at most one scheme.");
16737         }
16738 
16739         final int callingUid = Binder.getCallingUid();
16740         enforceCrossUserPermission(callingUid, userId,
16741                 true /* requireFullPermission */, false /* checkShell */,
16742                 "replace preferred activity");
16743         synchronized (mPackages) {
16744             if (mContext.checkCallingOrSelfPermission(
16745                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
16746                     != PackageManager.PERMISSION_GRANTED) {
16747                 if (getUidTargetSdkVersionLockedLPr(callingUid)
16748                         < Build.VERSION_CODES.FROYO) {
16749                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
16750                             + Binder.getCallingUid());
16751                     return;
16752                 }
16753                 mContext.enforceCallingOrSelfPermission(
16754                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
16755             }
16756 
16757             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
16758             if (pir != null) {
16759                 // Get all of the existing entries that exactly match this filter.
16760                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
16761                 if (existing != null && existing.size() == 1) {
16762                     PreferredActivity cur = existing.get(0);
16763                     if (DEBUG_PREFERRED) {
16764                         Slog.i(TAG, "Checking replace of preferred:");
16765                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
16766                         if (!cur.mPref.mAlways) {
16767                             Slog.i(TAG, "  -- CUR; not mAlways!");
16768                         } else {
16769                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
16770                             Slog.i(TAG, "  -- CUR: mSet="
16771                                     + Arrays.toString(cur.mPref.mSetComponents));
16772                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
16773                             Slog.i(TAG, "  -- NEW: mMatch="
16774                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
16775                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
16776                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
16777                         }
16778                     }
16779                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
16780                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
16781                             && cur.mPref.sameSet(set)) {
16782                         // Setting the preferred activity to what it happens to be already
16783                         if (DEBUG_PREFERRED) {
16784                             Slog.i(TAG, "Replacing with same preferred activity "
16785                                     + cur.mPref.mShortComponent + " for user "
16786                                     + userId + ":");
16787                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
16788                         }
16789                         return;
16790                     }
16791                 }
16792 
16793                 if (existing != null) {
16794                     if (DEBUG_PREFERRED) {
16795                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
16796                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
16797                     }
16798                     for (int i = 0; i < existing.size(); i++) {
16799                         PreferredActivity pa = existing.get(i);
16800                         if (DEBUG_PREFERRED) {
16801                             Slog.i(TAG, "Removing existing preferred activity "
16802                                     + pa.mPref.mComponent + ":");
16803                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
16804                         }
16805                         pir.removeFilter(pa);
16806                     }
16807                 }
16808             }
16809             addPreferredActivityInternal(filter, match, set, activity, true, userId,
16810                     "Replacing preferred");
16811         }
16812     }
16813 
16814     @Override
clearPackagePreferredActivities(String packageName)16815     public void clearPackagePreferredActivities(String packageName) {
16816         final int uid = Binder.getCallingUid();
16817         // writer
16818         synchronized (mPackages) {
16819             PackageParser.Package pkg = mPackages.get(packageName);
16820             if (pkg == null || pkg.applicationInfo.uid != uid) {
16821                 if (mContext.checkCallingOrSelfPermission(
16822                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
16823                         != PackageManager.PERMISSION_GRANTED) {
16824                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
16825                             < Build.VERSION_CODES.FROYO) {
16826                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
16827                                 + Binder.getCallingUid());
16828                         return;
16829                     }
16830                     mContext.enforceCallingOrSelfPermission(
16831                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
16832                 }
16833             }
16834 
16835             int user = UserHandle.getCallingUserId();
16836             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
16837                 scheduleWritePackageRestrictionsLocked(user);
16838             }
16839         }
16840     }
16841 
16842     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearPackagePreferredActivitiesLPw(String packageName, int userId)16843     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
16844         ArrayList<PreferredActivity> removed = null;
16845         boolean changed = false;
16846         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
16847             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
16848             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
16849             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
16850                 continue;
16851             }
16852             Iterator<PreferredActivity> it = pir.filterIterator();
16853             while (it.hasNext()) {
16854                 PreferredActivity pa = it.next();
16855                 // Mark entry for removal only if it matches the package name
16856                 // and the entry is of type "always".
16857                 if (packageName == null ||
16858                         (pa.mPref.mComponent.getPackageName().equals(packageName)
16859                                 && pa.mPref.mAlways)) {
16860                     if (removed == null) {
16861                         removed = new ArrayList<PreferredActivity>();
16862                     }
16863                     removed.add(pa);
16864                 }
16865             }
16866             if (removed != null) {
16867                 for (int j=0; j<removed.size(); j++) {
16868                     PreferredActivity pa = removed.get(j);
16869                     pir.removeFilter(pa);
16870                 }
16871                 changed = true;
16872             }
16873         }
16874         if (changed) {
16875             postPreferredActivityChangedBroadcast(userId);
16876         }
16877         return changed;
16878     }
16879 
16880     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearIntentFilterVerificationsLPw(int userId)16881     private void clearIntentFilterVerificationsLPw(int userId) {
16882         final int packageCount = mPackages.size();
16883         for (int i = 0; i < packageCount; i++) {
16884             PackageParser.Package pkg = mPackages.valueAt(i);
16885             clearIntentFilterVerificationsLPw(pkg.packageName, userId);
16886         }
16887     }
16888 
16889     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearIntentFilterVerificationsLPw(String packageName, int userId)16890     void clearIntentFilterVerificationsLPw(String packageName, int userId) {
16891         if (userId == UserHandle.USER_ALL) {
16892             if (mSettings.removeIntentFilterVerificationLPw(packageName,
16893                     sUserManager.getUserIds())) {
16894                 for (int oneUserId : sUserManager.getUserIds()) {
16895                     scheduleWritePackageRestrictionsLocked(oneUserId);
16896                 }
16897             }
16898         } else {
16899             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
16900                 scheduleWritePackageRestrictionsLocked(userId);
16901             }
16902         }
16903     }
16904 
clearDefaultBrowserIfNeeded(String packageName)16905     void clearDefaultBrowserIfNeeded(String packageName) {
16906         for (int oneUserId : sUserManager.getUserIds()) {
16907             String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
16908             if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
16909             if (packageName.equals(defaultBrowserPackageName)) {
16910                 setDefaultBrowserPackageName(null, oneUserId);
16911             }
16912         }
16913     }
16914 
16915     @Override
resetApplicationPreferences(int userId)16916     public void resetApplicationPreferences(int userId) {
16917         mContext.enforceCallingOrSelfPermission(
16918                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
16919         final long identity = Binder.clearCallingIdentity();
16920         // writer
16921         try {
16922             synchronized (mPackages) {
16923                 clearPackagePreferredActivitiesLPw(null, userId);
16924                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
16925                 // TODO: We have to reset the default SMS and Phone. This requires
16926                 // significant refactoring to keep all default apps in the package
16927                 // manager (cleaner but more work) or have the services provide
16928                 // callbacks to the package manager to request a default app reset.
16929                 applyFactoryDefaultBrowserLPw(userId);
16930                 clearIntentFilterVerificationsLPw(userId);
16931                 primeDomainVerificationsLPw(userId);
16932                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
16933                 scheduleWritePackageRestrictionsLocked(userId);
16934             }
16935             resetNetworkPolicies(userId);
16936         } finally {
16937             Binder.restoreCallingIdentity(identity);
16938         }
16939     }
16940 
16941     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)16942     public int getPreferredActivities(List<IntentFilter> outFilters,
16943             List<ComponentName> outActivities, String packageName) {
16944 
16945         int num = 0;
16946         final int userId = UserHandle.getCallingUserId();
16947         // reader
16948         synchronized (mPackages) {
16949             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
16950             if (pir != null) {
16951                 final Iterator<PreferredActivity> it = pir.filterIterator();
16952                 while (it.hasNext()) {
16953                     final PreferredActivity pa = it.next();
16954                     if (packageName == null
16955                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
16956                                     && pa.mPref.mAlways)) {
16957                         if (outFilters != null) {
16958                             outFilters.add(new IntentFilter(pa));
16959                         }
16960                         if (outActivities != null) {
16961                             outActivities.add(pa.mPref.mComponent);
16962                         }
16963                     }
16964                 }
16965             }
16966         }
16967 
16968         return num;
16969     }
16970 
16971     @Override
addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)16972     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
16973             int userId) {
16974         int callingUid = Binder.getCallingUid();
16975         if (callingUid != Process.SYSTEM_UID) {
16976             throw new SecurityException(
16977                     "addPersistentPreferredActivity can only be run by the system");
16978         }
16979         if (filter.countActions() == 0) {
16980             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
16981             return;
16982         }
16983         synchronized (mPackages) {
16984             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
16985                     ":");
16986             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
16987             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
16988                     new PersistentPreferredActivity(filter, activity));
16989             scheduleWritePackageRestrictionsLocked(userId);
16990             postPreferredActivityChangedBroadcast(userId);
16991         }
16992     }
16993 
16994     @Override
clearPackagePersistentPreferredActivities(String packageName, int userId)16995     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
16996         int callingUid = Binder.getCallingUid();
16997         if (callingUid != Process.SYSTEM_UID) {
16998             throw new SecurityException(
16999                     "clearPackagePersistentPreferredActivities can only be run by the system");
17000         }
17001         ArrayList<PersistentPreferredActivity> removed = null;
17002         boolean changed = false;
17003         synchronized (mPackages) {
17004             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
17005                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
17006                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
17007                         .valueAt(i);
17008                 if (userId != thisUserId) {
17009                     continue;
17010                 }
17011                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
17012                 while (it.hasNext()) {
17013                     PersistentPreferredActivity ppa = it.next();
17014                     // Mark entry for removal only if it matches the package name.
17015                     if (ppa.mComponent.getPackageName().equals(packageName)) {
17016                         if (removed == null) {
17017                             removed = new ArrayList<PersistentPreferredActivity>();
17018                         }
17019                         removed.add(ppa);
17020                     }
17021                 }
17022                 if (removed != null) {
17023                     for (int j=0; j<removed.size(); j++) {
17024                         PersistentPreferredActivity ppa = removed.get(j);
17025                         ppir.removeFilter(ppa);
17026                     }
17027                     changed = true;
17028                 }
17029             }
17030 
17031             if (changed) {
17032                 scheduleWritePackageRestrictionsLocked(userId);
17033                 postPreferredActivityChangedBroadcast(userId);
17034             }
17035         }
17036     }
17037 
17038     /**
17039      * Common machinery for picking apart a restored XML blob and passing
17040      * it to a caller-supplied functor to be applied to the running system.
17041      */
restoreFromXml(XmlPullParser parser, int userId, String expectedStartTag, BlobXmlRestorer functor)17042     private void restoreFromXml(XmlPullParser parser, int userId,
17043             String expectedStartTag, BlobXmlRestorer functor)
17044             throws IOException, XmlPullParserException {
17045         int type;
17046         while ((type = parser.next()) != XmlPullParser.START_TAG
17047                 && type != XmlPullParser.END_DOCUMENT) {
17048         }
17049         if (type != XmlPullParser.START_TAG) {
17050             // oops didn't find a start tag?!
17051             if (DEBUG_BACKUP) {
17052                 Slog.e(TAG, "Didn't find start tag during restore");
17053             }
17054             return;
17055         }
17056 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
17057         // this is supposed to be TAG_PREFERRED_BACKUP
17058         if (!expectedStartTag.equals(parser.getName())) {
17059             if (DEBUG_BACKUP) {
17060                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
17061             }
17062             return;
17063         }
17064 
17065         // skip interfering stuff, then we're aligned with the backing implementation
17066         while ((type = parser.next()) == XmlPullParser.TEXT) { }
17067 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
17068         functor.apply(parser, userId);
17069     }
17070 
17071     private interface BlobXmlRestorer {
17072         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
17073     }
17074 
17075     /**
17076      * Non-Binder method, support for the backup/restore mechanism: write the
17077      * full set of preferred activities in its canonical XML format.  Returns the
17078      * XML output as a byte array, or null if there is none.
17079      */
17080     @Override
getPreferredActivityBackup(int userId)17081     public byte[] getPreferredActivityBackup(int userId) {
17082         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17083             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
17084         }
17085 
17086         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17087         try {
17088             final XmlSerializer serializer = new FastXmlSerializer();
17089             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17090             serializer.startDocument(null, true);
17091             serializer.startTag(null, TAG_PREFERRED_BACKUP);
17092 
17093             synchronized (mPackages) {
17094                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
17095             }
17096 
17097             serializer.endTag(null, TAG_PREFERRED_BACKUP);
17098             serializer.endDocument();
17099             serializer.flush();
17100         } catch (Exception e) {
17101             if (DEBUG_BACKUP) {
17102                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
17103             }
17104             return null;
17105         }
17106 
17107         return dataStream.toByteArray();
17108     }
17109 
17110     @Override
restorePreferredActivities(byte[] backup, int userId)17111     public void restorePreferredActivities(byte[] backup, int userId) {
17112         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17113             throw new SecurityException("Only the system may call restorePreferredActivities()");
17114         }
17115 
17116         try {
17117             final XmlPullParser parser = Xml.newPullParser();
17118             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17119             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
17120                     new BlobXmlRestorer() {
17121                         @Override
17122                         public void apply(XmlPullParser parser, int userId)
17123                                 throws XmlPullParserException, IOException {
17124                             synchronized (mPackages) {
17125                                 mSettings.readPreferredActivitiesLPw(parser, userId);
17126                             }
17127                         }
17128                     } );
17129         } catch (Exception e) {
17130             if (DEBUG_BACKUP) {
17131                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17132             }
17133         }
17134     }
17135 
17136     /**
17137      * Non-Binder method, support for the backup/restore mechanism: write the
17138      * default browser (etc) settings in its canonical XML format.  Returns the default
17139      * browser XML representation as a byte array, or null if there is none.
17140      */
17141     @Override
getDefaultAppsBackup(int userId)17142     public byte[] getDefaultAppsBackup(int userId) {
17143         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17144             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
17145         }
17146 
17147         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17148         try {
17149             final XmlSerializer serializer = new FastXmlSerializer();
17150             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17151             serializer.startDocument(null, true);
17152             serializer.startTag(null, TAG_DEFAULT_APPS);
17153 
17154             synchronized (mPackages) {
17155                 mSettings.writeDefaultAppsLPr(serializer, userId);
17156             }
17157 
17158             serializer.endTag(null, TAG_DEFAULT_APPS);
17159             serializer.endDocument();
17160             serializer.flush();
17161         } catch (Exception e) {
17162             if (DEBUG_BACKUP) {
17163                 Slog.e(TAG, "Unable to write default apps for backup", e);
17164             }
17165             return null;
17166         }
17167 
17168         return dataStream.toByteArray();
17169     }
17170 
17171     @Override
restoreDefaultApps(byte[] backup, int userId)17172     public void restoreDefaultApps(byte[] backup, int userId) {
17173         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17174             throw new SecurityException("Only the system may call restoreDefaultApps()");
17175         }
17176 
17177         try {
17178             final XmlPullParser parser = Xml.newPullParser();
17179             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17180             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
17181                     new BlobXmlRestorer() {
17182                         @Override
17183                         public void apply(XmlPullParser parser, int userId)
17184                                 throws XmlPullParserException, IOException {
17185                             synchronized (mPackages) {
17186                                 mSettings.readDefaultAppsLPw(parser, userId);
17187                             }
17188                         }
17189                     } );
17190         } catch (Exception e) {
17191             if (DEBUG_BACKUP) {
17192                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
17193             }
17194         }
17195     }
17196 
17197     @Override
getIntentFilterVerificationBackup(int userId)17198     public byte[] getIntentFilterVerificationBackup(int userId) {
17199         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17200             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
17201         }
17202 
17203         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17204         try {
17205             final XmlSerializer serializer = new FastXmlSerializer();
17206             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17207             serializer.startDocument(null, true);
17208             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
17209 
17210             synchronized (mPackages) {
17211                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
17212             }
17213 
17214             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
17215             serializer.endDocument();
17216             serializer.flush();
17217         } catch (Exception e) {
17218             if (DEBUG_BACKUP) {
17219                 Slog.e(TAG, "Unable to write default apps for backup", e);
17220             }
17221             return null;
17222         }
17223 
17224         return dataStream.toByteArray();
17225     }
17226 
17227     @Override
restoreIntentFilterVerification(byte[] backup, int userId)17228     public void restoreIntentFilterVerification(byte[] backup, int userId) {
17229         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17230             throw new SecurityException("Only the system may call restorePreferredActivities()");
17231         }
17232 
17233         try {
17234             final XmlPullParser parser = Xml.newPullParser();
17235             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17236             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
17237                     new BlobXmlRestorer() {
17238                         @Override
17239                         public void apply(XmlPullParser parser, int userId)
17240                                 throws XmlPullParserException, IOException {
17241                             synchronized (mPackages) {
17242                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
17243                                 mSettings.writeLPr();
17244                             }
17245                         }
17246                     } );
17247         } catch (Exception e) {
17248             if (DEBUG_BACKUP) {
17249                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17250             }
17251         }
17252     }
17253 
17254     @Override
getPermissionGrantBackup(int userId)17255     public byte[] getPermissionGrantBackup(int userId) {
17256         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17257             throw new SecurityException("Only the system may call getPermissionGrantBackup()");
17258         }
17259 
17260         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17261         try {
17262             final XmlSerializer serializer = new FastXmlSerializer();
17263             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17264             serializer.startDocument(null, true);
17265             serializer.startTag(null, TAG_PERMISSION_BACKUP);
17266 
17267             synchronized (mPackages) {
17268                 serializeRuntimePermissionGrantsLPr(serializer, userId);
17269             }
17270 
17271             serializer.endTag(null, TAG_PERMISSION_BACKUP);
17272             serializer.endDocument();
17273             serializer.flush();
17274         } catch (Exception e) {
17275             if (DEBUG_BACKUP) {
17276                 Slog.e(TAG, "Unable to write default apps for backup", e);
17277             }
17278             return null;
17279         }
17280 
17281         return dataStream.toByteArray();
17282     }
17283 
17284     @Override
restorePermissionGrants(byte[] backup, int userId)17285     public void restorePermissionGrants(byte[] backup, int userId) {
17286         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17287             throw new SecurityException("Only the system may call restorePermissionGrants()");
17288         }
17289 
17290         try {
17291             final XmlPullParser parser = Xml.newPullParser();
17292             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17293             restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
17294                     new BlobXmlRestorer() {
17295                         @Override
17296                         public void apply(XmlPullParser parser, int userId)
17297                                 throws XmlPullParserException, IOException {
17298                             synchronized (mPackages) {
17299                                 processRestoredPermissionGrantsLPr(parser, userId);
17300                             }
17301                         }
17302                     } );
17303         } catch (Exception e) {
17304             if (DEBUG_BACKUP) {
17305                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17306             }
17307         }
17308     }
17309 
serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)17310     private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
17311             throws IOException {
17312         serializer.startTag(null, TAG_ALL_GRANTS);
17313 
17314         final int N = mSettings.mPackages.size();
17315         for (int i = 0; i < N; i++) {
17316             final PackageSetting ps = mSettings.mPackages.valueAt(i);
17317             boolean pkgGrantsKnown = false;
17318 
17319             PermissionsState packagePerms = ps.getPermissionsState();
17320 
17321             for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
17322                 final int grantFlags = state.getFlags();
17323                 // only look at grants that are not system/policy fixed
17324                 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
17325                     final boolean isGranted = state.isGranted();
17326                     // And only back up the user-twiddled state bits
17327                     if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
17328                         final String packageName = mSettings.mPackages.keyAt(i);
17329                         if (!pkgGrantsKnown) {
17330                             serializer.startTag(null, TAG_GRANT);
17331                             serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
17332                             pkgGrantsKnown = true;
17333                         }
17334 
17335                         final boolean userSet =
17336                                 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
17337                         final boolean userFixed =
17338                                 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
17339                         final boolean revoke =
17340                                 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
17341 
17342                         serializer.startTag(null, TAG_PERMISSION);
17343                         serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
17344                         if (isGranted) {
17345                             serializer.attribute(null, ATTR_IS_GRANTED, "true");
17346                         }
17347                         if (userSet) {
17348                             serializer.attribute(null, ATTR_USER_SET, "true");
17349                         }
17350                         if (userFixed) {
17351                             serializer.attribute(null, ATTR_USER_FIXED, "true");
17352                         }
17353                         if (revoke) {
17354                             serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
17355                         }
17356                         serializer.endTag(null, TAG_PERMISSION);
17357                     }
17358                 }
17359             }
17360 
17361             if (pkgGrantsKnown) {
17362                 serializer.endTag(null, TAG_GRANT);
17363             }
17364         }
17365 
17366         serializer.endTag(null, TAG_ALL_GRANTS);
17367     }
17368 
processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)17369     private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
17370             throws XmlPullParserException, IOException {
17371         String pkgName = null;
17372         int outerDepth = parser.getDepth();
17373         int type;
17374         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
17375                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
17376             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
17377                 continue;
17378             }
17379 
17380             final String tagName = parser.getName();
17381             if (tagName.equals(TAG_GRANT)) {
17382                 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
17383                 if (DEBUG_BACKUP) {
17384                     Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
17385                 }
17386             } else if (tagName.equals(TAG_PERMISSION)) {
17387 
17388                 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
17389                 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
17390 
17391                 int newFlagSet = 0;
17392                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
17393                     newFlagSet |= FLAG_PERMISSION_USER_SET;
17394                 }
17395                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
17396                     newFlagSet |= FLAG_PERMISSION_USER_FIXED;
17397                 }
17398                 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
17399                     newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
17400                 }
17401                 if (DEBUG_BACKUP) {
17402                     Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
17403                             + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
17404                 }
17405                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17406                 if (ps != null) {
17407                     // Already installed so we apply the grant immediately
17408                     if (DEBUG_BACKUP) {
17409                         Slog.v(TAG, "        + already installed; applying");
17410                     }
17411                     PermissionsState perms = ps.getPermissionsState();
17412                     BasePermission bp = mSettings.mPermissions.get(permName);
17413                     if (bp != null) {
17414                         if (isGranted) {
17415                             perms.grantRuntimePermission(bp, userId);
17416                         }
17417                         if (newFlagSet != 0) {
17418                             perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
17419                         }
17420                     }
17421                 } else {
17422                     // Need to wait for post-restore install to apply the grant
17423                     if (DEBUG_BACKUP) {
17424                         Slog.v(TAG, "        - not yet installed; saving for later");
17425                     }
17426                     mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
17427                             isGranted, newFlagSet, userId);
17428                 }
17429             } else {
17430                 PackageManagerService.reportSettingsProblem(Log.WARN,
17431                         "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
17432                 XmlUtils.skipCurrentTag(parser);
17433             }
17434         }
17435 
17436         scheduleWriteSettingsLocked();
17437         mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17438     }
17439 
17440     @Override
addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)17441     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
17442             int sourceUserId, int targetUserId, int flags) {
17443         mContext.enforceCallingOrSelfPermission(
17444                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17445         int callingUid = Binder.getCallingUid();
17446         enforceOwnerRights(ownerPackage, callingUid);
17447         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17448         if (intentFilter.countActions() == 0) {
17449             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
17450             return;
17451         }
17452         synchronized (mPackages) {
17453             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
17454                     ownerPackage, targetUserId, flags);
17455             CrossProfileIntentResolver resolver =
17456                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17457             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
17458             // We have all those whose filter is equal. Now checking if the rest is equal as well.
17459             if (existing != null) {
17460                 int size = existing.size();
17461                 for (int i = 0; i < size; i++) {
17462                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
17463                         return;
17464                     }
17465                 }
17466             }
17467             resolver.addFilter(newFilter);
17468             scheduleWritePackageRestrictionsLocked(sourceUserId);
17469         }
17470     }
17471 
17472     @Override
clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage)17473     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
17474         mContext.enforceCallingOrSelfPermission(
17475                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17476         int callingUid = Binder.getCallingUid();
17477         enforceOwnerRights(ownerPackage, callingUid);
17478         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17479         synchronized (mPackages) {
17480             CrossProfileIntentResolver resolver =
17481                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17482             ArraySet<CrossProfileIntentFilter> set =
17483                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
17484             for (CrossProfileIntentFilter filter : set) {
17485                 if (filter.getOwnerPackage().equals(ownerPackage)) {
17486                     resolver.removeFilter(filter);
17487                 }
17488             }
17489             scheduleWritePackageRestrictionsLocked(sourceUserId);
17490         }
17491     }
17492 
17493     // Enforcing that callingUid is owning pkg on userId
enforceOwnerRights(String pkg, int callingUid)17494     private void enforceOwnerRights(String pkg, int callingUid) {
17495         // The system owns everything.
17496         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17497             return;
17498         }
17499         int callingUserId = UserHandle.getUserId(callingUid);
17500         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
17501         if (pi == null) {
17502             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
17503                     + callingUserId);
17504         }
17505         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
17506             throw new SecurityException("Calling uid " + callingUid
17507                     + " does not own package " + pkg);
17508         }
17509     }
17510 
17511     @Override
getHomeActivities(List<ResolveInfo> allHomeCandidates)17512     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
17513         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
17514     }
17515 
getHomeIntent()17516     private Intent getHomeIntent() {
17517         Intent intent = new Intent(Intent.ACTION_MAIN);
17518         intent.addCategory(Intent.CATEGORY_HOME);
17519         intent.addCategory(Intent.CATEGORY_DEFAULT);
17520         return intent;
17521     }
17522 
getHomeFilter()17523     private IntentFilter getHomeFilter() {
17524         IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
17525         filter.addCategory(Intent.CATEGORY_HOME);
17526         filter.addCategory(Intent.CATEGORY_DEFAULT);
17527         return filter;
17528     }
17529 
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)17530     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
17531             int userId) {
17532         Intent intent  = getHomeIntent();
17533         List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
17534                 PackageManager.GET_META_DATA, userId);
17535         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
17536                 true, false, false, userId);
17537 
17538         allHomeCandidates.clear();
17539         if (list != null) {
17540             for (ResolveInfo ri : list) {
17541                 allHomeCandidates.add(ri);
17542             }
17543         }
17544         return (preferred == null || preferred.activityInfo == null)
17545                 ? null
17546                 : new ComponentName(preferred.activityInfo.packageName,
17547                         preferred.activityInfo.name);
17548     }
17549 
17550     @Override
setHomeActivity(ComponentName comp, int userId)17551     public void setHomeActivity(ComponentName comp, int userId) {
17552         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
17553         getHomeActivitiesAsUser(homeActivities, userId);
17554 
17555         boolean found = false;
17556 
17557         final int size = homeActivities.size();
17558         final ComponentName[] set = new ComponentName[size];
17559         for (int i = 0; i < size; i++) {
17560             final ResolveInfo candidate = homeActivities.get(i);
17561             final ActivityInfo info = candidate.activityInfo;
17562             final ComponentName activityName = new ComponentName(info.packageName, info.name);
17563             set[i] = activityName;
17564             if (!found && activityName.equals(comp)) {
17565                 found = true;
17566             }
17567         }
17568         if (!found) {
17569             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
17570                     + userId);
17571         }
17572         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
17573                 set, comp, userId);
17574     }
17575 
getSetupWizardPackageName()17576     private @Nullable String getSetupWizardPackageName() {
17577         final Intent intent = new Intent(Intent.ACTION_MAIN);
17578         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
17579 
17580         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
17581                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
17582                         | MATCH_DISABLED_COMPONENTS,
17583                 UserHandle.myUserId());
17584         if (matches.size() == 1) {
17585             return matches.get(0).getComponentInfo().packageName;
17586         } else {
17587             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
17588                     + ": matches=" + matches);
17589             return null;
17590         }
17591     }
17592 
17593     @Override
setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)17594     public void setApplicationEnabledSetting(String appPackageName,
17595             int newState, int flags, int userId, String callingPackage) {
17596         if (!sUserManager.exists(userId)) return;
17597         if (callingPackage == null) {
17598             callingPackage = Integer.toString(Binder.getCallingUid());
17599         }
17600         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
17601     }
17602 
17603     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)17604     public void setComponentEnabledSetting(ComponentName componentName,
17605             int newState, int flags, int userId) {
17606         if (!sUserManager.exists(userId)) return;
17607         setEnabledSetting(componentName.getPackageName(),
17608                 componentName.getClassName(), newState, flags, userId, null);
17609     }
17610 
setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)17611     private void setEnabledSetting(final String packageName, String className, int newState,
17612             final int flags, int userId, String callingPackage) {
17613         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
17614               || newState == COMPONENT_ENABLED_STATE_ENABLED
17615               || newState == COMPONENT_ENABLED_STATE_DISABLED
17616               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
17617               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
17618             throw new IllegalArgumentException("Invalid new component state: "
17619                     + newState);
17620         }
17621         PackageSetting pkgSetting;
17622         final int uid = Binder.getCallingUid();
17623         final int permission;
17624         if (uid == Process.SYSTEM_UID) {
17625             permission = PackageManager.PERMISSION_GRANTED;
17626         } else {
17627             permission = mContext.checkCallingOrSelfPermission(
17628                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
17629         }
17630         enforceCrossUserPermission(uid, userId,
17631                 false /* requireFullPermission */, true /* checkShell */, "set enabled");
17632         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
17633         boolean sendNow = false;
17634         boolean isApp = (className == null);
17635         String componentName = isApp ? packageName : className;
17636         int packageUid = -1;
17637         ArrayList<String> components;
17638 
17639         // writer
17640         synchronized (mPackages) {
17641             pkgSetting = mSettings.mPackages.get(packageName);
17642             if (pkgSetting == null) {
17643                 if (className == null) {
17644                     throw new IllegalArgumentException("Unknown package: " + packageName);
17645                 }
17646                 throw new IllegalArgumentException(
17647                         "Unknown component: " + packageName + "/" + className);
17648             }
17649         }
17650 
17651         // Limit who can change which apps
17652         if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
17653             // Don't allow apps that don't have permission to modify other apps
17654             if (!allowedByPermission) {
17655                 throw new SecurityException(
17656                         "Permission Denial: attempt to change component state from pid="
17657                         + Binder.getCallingPid()
17658                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
17659             }
17660             // Don't allow changing protected packages.
17661             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
17662                 throw new SecurityException("Cannot disable a protected package: " + packageName);
17663             }
17664         }
17665 
17666         synchronized (mPackages) {
17667             if (uid == Process.SHELL_UID) {
17668                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
17669                 int oldState = pkgSetting.getEnabled(userId);
17670                 if (className == null
17671                     &&
17672                     (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
17673                      || oldState == COMPONENT_ENABLED_STATE_DEFAULT
17674                      || oldState == COMPONENT_ENABLED_STATE_ENABLED)
17675                     &&
17676                     (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
17677                      || newState == COMPONENT_ENABLED_STATE_DEFAULT
17678                      || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
17679                     // ok
17680                 } else {
17681                     throw new SecurityException(
17682                             "Shell cannot change component state for " + packageName + "/"
17683                             + className + " to " + newState);
17684                 }
17685             }
17686             if (className == null) {
17687                 // We're dealing with an application/package level state change
17688                 if (pkgSetting.getEnabled(userId) == newState) {
17689                     // Nothing to do
17690                     return;
17691                 }
17692                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
17693                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
17694                     // Don't care about who enables an app.
17695                     callingPackage = null;
17696                 }
17697                 pkgSetting.setEnabled(newState, userId, callingPackage);
17698                 // pkgSetting.pkg.mSetEnabled = newState;
17699             } else {
17700                 // We're dealing with a component level state change
17701                 // First, verify that this is a valid class name.
17702                 PackageParser.Package pkg = pkgSetting.pkg;
17703                 if (pkg == null || !pkg.hasComponentClassName(className)) {
17704                     if (pkg != null &&
17705                             pkg.applicationInfo.targetSdkVersion >=
17706                                     Build.VERSION_CODES.JELLY_BEAN) {
17707                         throw new IllegalArgumentException("Component class " + className
17708                                 + " does not exist in " + packageName);
17709                     } else {
17710                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
17711                                 + className + " does not exist in " + packageName);
17712                     }
17713                 }
17714                 switch (newState) {
17715                 case COMPONENT_ENABLED_STATE_ENABLED:
17716                     if (!pkgSetting.enableComponentLPw(className, userId)) {
17717                         return;
17718                     }
17719                     break;
17720                 case COMPONENT_ENABLED_STATE_DISABLED:
17721                     if (!pkgSetting.disableComponentLPw(className, userId)) {
17722                         return;
17723                     }
17724                     break;
17725                 case COMPONENT_ENABLED_STATE_DEFAULT:
17726                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
17727                         return;
17728                     }
17729                     break;
17730                 default:
17731                     Slog.e(TAG, "Invalid new component state: " + newState);
17732                     return;
17733                 }
17734             }
17735             scheduleWritePackageRestrictionsLocked(userId);
17736             components = mPendingBroadcasts.get(userId, packageName);
17737             final boolean newPackage = components == null;
17738             if (newPackage) {
17739                 components = new ArrayList<String>();
17740             }
17741             if (!components.contains(componentName)) {
17742                 components.add(componentName);
17743             }
17744             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
17745                 sendNow = true;
17746                 // Purge entry from pending broadcast list if another one exists already
17747                 // since we are sending one right away.
17748                 mPendingBroadcasts.remove(userId, packageName);
17749             } else {
17750                 if (newPackage) {
17751                     mPendingBroadcasts.put(userId, packageName, components);
17752                 }
17753                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
17754                     // Schedule a message
17755                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
17756                 }
17757             }
17758         }
17759 
17760         long callingId = Binder.clearCallingIdentity();
17761         try {
17762             if (sendNow) {
17763                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
17764                 sendPackageChangedBroadcast(packageName,
17765                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
17766             }
17767         } finally {
17768             Binder.restoreCallingIdentity(callingId);
17769         }
17770     }
17771 
17772     @Override
flushPackageRestrictionsAsUser(int userId)17773     public void flushPackageRestrictionsAsUser(int userId) {
17774         if (!sUserManager.exists(userId)) {
17775             return;
17776         }
17777         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
17778                 false /* checkShell */, "flushPackageRestrictions");
17779         synchronized (mPackages) {
17780             mSettings.writePackageRestrictionsLPr(userId);
17781             mDirtyUsers.remove(userId);
17782             if (mDirtyUsers.isEmpty()) {
17783                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
17784             }
17785         }
17786     }
17787 
sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)17788     private void sendPackageChangedBroadcast(String packageName,
17789             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
17790         if (DEBUG_INSTALL)
17791             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
17792                     + componentNames);
17793         Bundle extras = new Bundle(4);
17794         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
17795         String nameList[] = new String[componentNames.size()];
17796         componentNames.toArray(nameList);
17797         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
17798         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
17799         extras.putInt(Intent.EXTRA_UID, packageUid);
17800         // If this is not reporting a change of the overall package, then only send it
17801         // to registered receivers.  We don't want to launch a swath of apps for every
17802         // little component state change.
17803         final int flags = !componentNames.contains(packageName)
17804                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
17805         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
17806                 new int[] {UserHandle.getUserId(packageUid)});
17807     }
17808 
17809     @Override
setPackageStoppedState(String packageName, boolean stopped, int userId)17810     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
17811         if (!sUserManager.exists(userId)) return;
17812         final int uid = Binder.getCallingUid();
17813         final int permission = mContext.checkCallingOrSelfPermission(
17814                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
17815         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
17816         enforceCrossUserPermission(uid, userId,
17817                 true /* requireFullPermission */, true /* checkShell */, "stop package");
17818         // writer
17819         synchronized (mPackages) {
17820             if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
17821                     allowedByPermission, uid, userId)) {
17822                 scheduleWritePackageRestrictionsLocked(userId);
17823             }
17824         }
17825     }
17826 
17827     @Override
getInstallerPackageName(String packageName)17828     public String getInstallerPackageName(String packageName) {
17829         // reader
17830         synchronized (mPackages) {
17831             return mSettings.getInstallerPackageNameLPr(packageName);
17832         }
17833     }
17834 
isOrphaned(String packageName)17835     public boolean isOrphaned(String packageName) {
17836         // reader
17837         synchronized (mPackages) {
17838             return mSettings.isOrphaned(packageName);
17839         }
17840     }
17841 
17842     @Override
getApplicationEnabledSetting(String packageName, int userId)17843     public int getApplicationEnabledSetting(String packageName, int userId) {
17844         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
17845         int uid = Binder.getCallingUid();
17846         enforceCrossUserPermission(uid, userId,
17847                 false /* requireFullPermission */, false /* checkShell */, "get enabled");
17848         // reader
17849         synchronized (mPackages) {
17850             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
17851         }
17852     }
17853 
17854     @Override
getComponentEnabledSetting(ComponentName componentName, int userId)17855     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
17856         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
17857         int uid = Binder.getCallingUid();
17858         enforceCrossUserPermission(uid, userId,
17859                 false /* requireFullPermission */, false /* checkShell */, "get component enabled");
17860         // reader
17861         synchronized (mPackages) {
17862             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
17863         }
17864     }
17865 
17866     @Override
enterSafeMode()17867     public void enterSafeMode() {
17868         enforceSystemOrRoot("Only the system can request entering safe mode");
17869 
17870         if (!mSystemReady) {
17871             mSafeMode = true;
17872         }
17873     }
17874 
17875     @Override
systemReady()17876     public void systemReady() {
17877         mSystemReady = true;
17878 
17879         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
17880         // disabled after already being started.
17881         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
17882                 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
17883 
17884         // Read the compatibilty setting when the system is ready.
17885         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
17886                 mContext.getContentResolver(),
17887                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
17888         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
17889         if (DEBUG_SETTINGS) {
17890             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
17891         }
17892 
17893         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
17894 
17895         synchronized (mPackages) {
17896             // Verify that all of the preferred activity components actually
17897             // exist.  It is possible for applications to be updated and at
17898             // that point remove a previously declared activity component that
17899             // had been set as a preferred activity.  We try to clean this up
17900             // the next time we encounter that preferred activity, but it is
17901             // possible for the user flow to never be able to return to that
17902             // situation so here we do a sanity check to make sure we haven't
17903             // left any junk around.
17904             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
17905             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
17906                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
17907                 removed.clear();
17908                 for (PreferredActivity pa : pir.filterSet()) {
17909                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
17910                         removed.add(pa);
17911                     }
17912                 }
17913                 if (removed.size() > 0) {
17914                     for (int r=0; r<removed.size(); r++) {
17915                         PreferredActivity pa = removed.get(r);
17916                         Slog.w(TAG, "Removing dangling preferred activity: "
17917                                 + pa.mPref.mComponent);
17918                         pir.removeFilter(pa);
17919                     }
17920                     mSettings.writePackageRestrictionsLPr(
17921                             mSettings.mPreferredActivities.keyAt(i));
17922                 }
17923             }
17924 
17925             for (int userId : UserManagerService.getInstance().getUserIds()) {
17926                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
17927                     grantPermissionsUserIds = ArrayUtils.appendInt(
17928                             grantPermissionsUserIds, userId);
17929                 }
17930             }
17931         }
17932         sUserManager.systemReady();
17933 
17934         // If we upgraded grant all default permissions before kicking off.
17935         for (int userId : grantPermissionsUserIds) {
17936             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
17937         }
17938 
17939         // If we did not grant default permissions, we preload from this the
17940         // default permission exceptions lazily to ensure we don't hit the
17941         // disk on a new user creation.
17942         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
17943             mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
17944         }
17945 
17946         // Kick off any messages waiting for system ready
17947         if (mPostSystemReadyMessages != null) {
17948             for (Message msg : mPostSystemReadyMessages) {
17949                 msg.sendToTarget();
17950             }
17951             mPostSystemReadyMessages = null;
17952         }
17953 
17954         // Watch for external volumes that come and go over time
17955         final StorageManager storage = mContext.getSystemService(StorageManager.class);
17956         storage.registerListener(mStorageListener);
17957 
17958         mInstallerService.systemReady();
17959         mPackageDexOptimizer.systemReady();
17960 
17961         MountServiceInternal mountServiceInternal = LocalServices.getService(
17962                 MountServiceInternal.class);
17963         mountServiceInternal.addExternalStoragePolicy(
17964                 new MountServiceInternal.ExternalStorageMountPolicy() {
17965             @Override
17966             public int getMountMode(int uid, String packageName) {
17967                 if (Process.isIsolated(uid)) {
17968                     return Zygote.MOUNT_EXTERNAL_NONE;
17969                 }
17970                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
17971                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
17972                 }
17973                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
17974                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
17975                 }
17976                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
17977                     return Zygote.MOUNT_EXTERNAL_READ;
17978                 }
17979                 return Zygote.MOUNT_EXTERNAL_WRITE;
17980             }
17981 
17982             @Override
17983             public boolean hasExternalStorage(int uid, String packageName) {
17984                 return true;
17985             }
17986         });
17987 
17988         // Now that we're mostly running, clean up stale users and apps
17989         reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
17990         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
17991     }
17992 
17993     @Override
isSafeMode()17994     public boolean isSafeMode() {
17995         return mSafeMode;
17996     }
17997 
17998     @Override
hasSystemUidErrors()17999     public boolean hasSystemUidErrors() {
18000         return mHasSystemUidErrors;
18001     }
18002 
arrayToString(int[] array)18003     static String arrayToString(int[] array) {
18004         StringBuffer buf = new StringBuffer(128);
18005         buf.append('[');
18006         if (array != null) {
18007             for (int i=0; i<array.length; i++) {
18008                 if (i > 0) buf.append(", ");
18009                 buf.append(array[i]);
18010             }
18011         }
18012         buf.append(']');
18013         return buf.toString();
18014     }
18015 
18016     static class DumpState {
18017         public static final int DUMP_LIBS = 1 << 0;
18018         public static final int DUMP_FEATURES = 1 << 1;
18019         public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
18020         public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
18021         public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
18022         public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
18023         public static final int DUMP_PERMISSIONS = 1 << 6;
18024         public static final int DUMP_PACKAGES = 1 << 7;
18025         public static final int DUMP_SHARED_USERS = 1 << 8;
18026         public static final int DUMP_MESSAGES = 1 << 9;
18027         public static final int DUMP_PROVIDERS = 1 << 10;
18028         public static final int DUMP_VERIFIERS = 1 << 11;
18029         public static final int DUMP_PREFERRED = 1 << 12;
18030         public static final int DUMP_PREFERRED_XML = 1 << 13;
18031         public static final int DUMP_KEYSETS = 1 << 14;
18032         public static final int DUMP_VERSION = 1 << 15;
18033         public static final int DUMP_INSTALLS = 1 << 16;
18034         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
18035         public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
18036         public static final int DUMP_FROZEN = 1 << 19;
18037         public static final int DUMP_DEXOPT = 1 << 20;
18038         public static final int DUMP_COMPILER_STATS = 1 << 21;
18039 
18040         public static final int OPTION_SHOW_FILTERS = 1 << 0;
18041 
18042         private int mTypes;
18043 
18044         private int mOptions;
18045 
18046         private boolean mTitlePrinted;
18047 
18048         private SharedUserSetting mSharedUser;
18049 
isDumping(int type)18050         public boolean isDumping(int type) {
18051             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
18052                 return true;
18053             }
18054 
18055             return (mTypes & type) != 0;
18056         }
18057 
setDump(int type)18058         public void setDump(int type) {
18059             mTypes |= type;
18060         }
18061 
isOptionEnabled(int option)18062         public boolean isOptionEnabled(int option) {
18063             return (mOptions & option) != 0;
18064         }
18065 
setOptionEnabled(int option)18066         public void setOptionEnabled(int option) {
18067             mOptions |= option;
18068         }
18069 
onTitlePrinted()18070         public boolean onTitlePrinted() {
18071             final boolean printed = mTitlePrinted;
18072             mTitlePrinted = true;
18073             return printed;
18074         }
18075 
getTitlePrinted()18076         public boolean getTitlePrinted() {
18077             return mTitlePrinted;
18078         }
18079 
setTitlePrinted(boolean enabled)18080         public void setTitlePrinted(boolean enabled) {
18081             mTitlePrinted = enabled;
18082         }
18083 
getSharedUser()18084         public SharedUserSetting getSharedUser() {
18085             return mSharedUser;
18086         }
18087 
setSharedUser(SharedUserSetting user)18088         public void setSharedUser(SharedUserSetting user) {
18089             mSharedUser = user;
18090         }
18091     }
18092 
18093     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ResultReceiver resultReceiver)18094     public void onShellCommand(FileDescriptor in, FileDescriptor out,
18095             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
18096         (new PackageManagerShellCommand(this)).exec(
18097                 this, in, out, err, args, resultReceiver);
18098     }
18099 
18100     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)18101     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
18102         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
18103                 != PackageManager.PERMISSION_GRANTED) {
18104             pw.println("Permission Denial: can't dump ActivityManager from from pid="
18105                     + Binder.getCallingPid()
18106                     + ", uid=" + Binder.getCallingUid()
18107                     + " without permission "
18108                     + android.Manifest.permission.DUMP);
18109             return;
18110         }
18111 
18112         DumpState dumpState = new DumpState();
18113         boolean fullPreferred = false;
18114         boolean checkin = false;
18115 
18116         String packageName = null;
18117         ArraySet<String> permissionNames = null;
18118 
18119         int opti = 0;
18120         while (opti < args.length) {
18121             String opt = args[opti];
18122             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18123                 break;
18124             }
18125             opti++;
18126 
18127             if ("-a".equals(opt)) {
18128                 // Right now we only know how to print all.
18129             } else if ("-h".equals(opt)) {
18130                 pw.println("Package manager dump options:");
18131                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
18132                 pw.println("    --checkin: dump for a checkin");
18133                 pw.println("    -f: print details of intent filters");
18134                 pw.println("    -h: print this help");
18135                 pw.println("  cmd may be one of:");
18136                 pw.println("    l[ibraries]: list known shared libraries");
18137                 pw.println("    f[eatures]: list device features");
18138                 pw.println("    k[eysets]: print known keysets");
18139                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
18140                 pw.println("    perm[issions]: dump permissions");
18141                 pw.println("    permission [name ...]: dump declaration and use of given permission");
18142                 pw.println("    pref[erred]: print preferred package settings");
18143                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
18144                 pw.println("    prov[iders]: dump content providers");
18145                 pw.println("    p[ackages]: dump installed packages");
18146                 pw.println("    s[hared-users]: dump shared user IDs");
18147                 pw.println("    m[essages]: print collected runtime messages");
18148                 pw.println("    v[erifiers]: print package verifier info");
18149                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
18150                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
18151                 pw.println("    version: print database version info");
18152                 pw.println("    write: write current settings now");
18153                 pw.println("    installs: details about install sessions");
18154                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
18155                 pw.println("    dexopt: dump dexopt state");
18156                 pw.println("    compiler-stats: dump compiler statistics");
18157                 pw.println("    <package.name>: info about given package");
18158                 return;
18159             } else if ("--checkin".equals(opt)) {
18160                 checkin = true;
18161             } else if ("-f".equals(opt)) {
18162                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18163             } else {
18164                 pw.println("Unknown argument: " + opt + "; use -h for help");
18165             }
18166         }
18167 
18168         // Is the caller requesting to dump a particular piece of data?
18169         if (opti < args.length) {
18170             String cmd = args[opti];
18171             opti++;
18172             // Is this a package name?
18173             if ("android".equals(cmd) || cmd.contains(".")) {
18174                 packageName = cmd;
18175                 // When dumping a single package, we always dump all of its
18176                 // filter information since the amount of data will be reasonable.
18177                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18178             } else if ("check-permission".equals(cmd)) {
18179                 if (opti >= args.length) {
18180                     pw.println("Error: check-permission missing permission argument");
18181                     return;
18182                 }
18183                 String perm = args[opti];
18184                 opti++;
18185                 if (opti >= args.length) {
18186                     pw.println("Error: check-permission missing package argument");
18187                     return;
18188                 }
18189                 String pkg = args[opti];
18190                 opti++;
18191                 int user = UserHandle.getUserId(Binder.getCallingUid());
18192                 if (opti < args.length) {
18193                     try {
18194                         user = Integer.parseInt(args[opti]);
18195                     } catch (NumberFormatException e) {
18196                         pw.println("Error: check-permission user argument is not a number: "
18197                                 + args[opti]);
18198                         return;
18199                     }
18200                 }
18201                 pw.println(checkPermission(perm, pkg, user));
18202                 return;
18203             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
18204                 dumpState.setDump(DumpState.DUMP_LIBS);
18205             } else if ("f".equals(cmd) || "features".equals(cmd)) {
18206                 dumpState.setDump(DumpState.DUMP_FEATURES);
18207             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
18208                 if (opti >= args.length) {
18209                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
18210                             | DumpState.DUMP_SERVICE_RESOLVERS
18211                             | DumpState.DUMP_RECEIVER_RESOLVERS
18212                             | DumpState.DUMP_CONTENT_RESOLVERS);
18213                 } else {
18214                     while (opti < args.length) {
18215                         String name = args[opti];
18216                         if ("a".equals(name) || "activity".equals(name)) {
18217                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
18218                         } else if ("s".equals(name) || "service".equals(name)) {
18219                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
18220                         } else if ("r".equals(name) || "receiver".equals(name)) {
18221                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
18222                         } else if ("c".equals(name) || "content".equals(name)) {
18223                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
18224                         } else {
18225                             pw.println("Error: unknown resolver table type: " + name);
18226                             return;
18227                         }
18228                         opti++;
18229                     }
18230                 }
18231             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
18232                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
18233             } else if ("permission".equals(cmd)) {
18234                 if (opti >= args.length) {
18235                     pw.println("Error: permission requires permission name");
18236                     return;
18237                 }
18238                 permissionNames = new ArraySet<>();
18239                 while (opti < args.length) {
18240                     permissionNames.add(args[opti]);
18241                     opti++;
18242                 }
18243                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
18244                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
18245             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
18246                 dumpState.setDump(DumpState.DUMP_PREFERRED);
18247             } else if ("preferred-xml".equals(cmd)) {
18248                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
18249                 if (opti < args.length && "--full".equals(args[opti])) {
18250                     fullPreferred = true;
18251                     opti++;
18252                 }
18253             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
18254                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
18255             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
18256                 dumpState.setDump(DumpState.DUMP_PACKAGES);
18257             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
18258                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
18259             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
18260                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
18261             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
18262                 dumpState.setDump(DumpState.DUMP_MESSAGES);
18263             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
18264                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
18265             } else if ("i".equals(cmd) || "ifv".equals(cmd)
18266                     || "intent-filter-verifiers".equals(cmd)) {
18267                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
18268             } else if ("version".equals(cmd)) {
18269                 dumpState.setDump(DumpState.DUMP_VERSION);
18270             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
18271                 dumpState.setDump(DumpState.DUMP_KEYSETS);
18272             } else if ("installs".equals(cmd)) {
18273                 dumpState.setDump(DumpState.DUMP_INSTALLS);
18274             } else if ("frozen".equals(cmd)) {
18275                 dumpState.setDump(DumpState.DUMP_FROZEN);
18276             } else if ("dexopt".equals(cmd)) {
18277                 dumpState.setDump(DumpState.DUMP_DEXOPT);
18278             } else if ("compiler-stats".equals(cmd)) {
18279                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
18280             } else if ("write".equals(cmd)) {
18281                 synchronized (mPackages) {
18282                     mSettings.writeLPr();
18283                     pw.println("Settings written.");
18284                     return;
18285                 }
18286             }
18287         }
18288 
18289         if (checkin) {
18290             pw.println("vers,1");
18291         }
18292 
18293         // reader
18294         synchronized (mPackages) {
18295             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
18296                 if (!checkin) {
18297                     if (dumpState.onTitlePrinted())
18298                         pw.println();
18299                     pw.println("Database versions:");
18300                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
18301                 }
18302             }
18303 
18304             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
18305                 if (!checkin) {
18306                     if (dumpState.onTitlePrinted())
18307                         pw.println();
18308                     pw.println("Verifiers:");
18309                     pw.print("  Required: ");
18310                     pw.print(mRequiredVerifierPackage);
18311                     pw.print(" (uid=");
18312                     pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18313                             UserHandle.USER_SYSTEM));
18314                     pw.println(")");
18315                 } else if (mRequiredVerifierPackage != null) {
18316                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
18317                     pw.print(",");
18318                     pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18319                             UserHandle.USER_SYSTEM));
18320                 }
18321             }
18322 
18323             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
18324                     packageName == null) {
18325                 if (mIntentFilterVerifierComponent != null) {
18326                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
18327                     if (!checkin) {
18328                         if (dumpState.onTitlePrinted())
18329                             pw.println();
18330                         pw.println("Intent Filter Verifier:");
18331                         pw.print("  Using: ");
18332                         pw.print(verifierPackageName);
18333                         pw.print(" (uid=");
18334                         pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18335                                 UserHandle.USER_SYSTEM));
18336                         pw.println(")");
18337                     } else if (verifierPackageName != null) {
18338                         pw.print("ifv,"); pw.print(verifierPackageName);
18339                         pw.print(",");
18340                         pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18341                                 UserHandle.USER_SYSTEM));
18342                     }
18343                 } else {
18344                     pw.println();
18345                     pw.println("No Intent Filter Verifier available!");
18346                 }
18347             }
18348 
18349             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
18350                 boolean printedHeader = false;
18351                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
18352                 while (it.hasNext()) {
18353                     String name = it.next();
18354                     SharedLibraryEntry ent = mSharedLibraries.get(name);
18355                     if (!checkin) {
18356                         if (!printedHeader) {
18357                             if (dumpState.onTitlePrinted())
18358                                 pw.println();
18359                             pw.println("Libraries:");
18360                             printedHeader = true;
18361                         }
18362                         pw.print("  ");
18363                     } else {
18364                         pw.print("lib,");
18365                     }
18366                     pw.print(name);
18367                     if (!checkin) {
18368                         pw.print(" -> ");
18369                     }
18370                     if (ent.path != null) {
18371                         if (!checkin) {
18372                             pw.print("(jar) ");
18373                             pw.print(ent.path);
18374                         } else {
18375                             pw.print(",jar,");
18376                             pw.print(ent.path);
18377                         }
18378                     } else {
18379                         if (!checkin) {
18380                             pw.print("(apk) ");
18381                             pw.print(ent.apk);
18382                         } else {
18383                             pw.print(",apk,");
18384                             pw.print(ent.apk);
18385                         }
18386                     }
18387                     pw.println();
18388                 }
18389             }
18390 
18391             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
18392                 if (dumpState.onTitlePrinted())
18393                     pw.println();
18394                 if (!checkin) {
18395                     pw.println("Features:");
18396                 }
18397 
18398                 for (FeatureInfo feat : mAvailableFeatures.values()) {
18399                     if (checkin) {
18400                         pw.print("feat,");
18401                         pw.print(feat.name);
18402                         pw.print(",");
18403                         pw.println(feat.version);
18404                     } else {
18405                         pw.print("  ");
18406                         pw.print(feat.name);
18407                         if (feat.version > 0) {
18408                             pw.print(" version=");
18409                             pw.print(feat.version);
18410                         }
18411                         pw.println();
18412                     }
18413                 }
18414             }
18415 
18416             if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
18417                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
18418                         : "Activity Resolver Table:", "  ", packageName,
18419                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18420                     dumpState.setTitlePrinted(true);
18421                 }
18422             }
18423             if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
18424                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
18425                         : "Receiver Resolver Table:", "  ", packageName,
18426                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18427                     dumpState.setTitlePrinted(true);
18428                 }
18429             }
18430             if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
18431                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
18432                         : "Service Resolver Table:", "  ", packageName,
18433                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18434                     dumpState.setTitlePrinted(true);
18435                 }
18436             }
18437             if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
18438                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
18439                         : "Provider Resolver Table:", "  ", packageName,
18440                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18441                     dumpState.setTitlePrinted(true);
18442                 }
18443             }
18444 
18445             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
18446                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18447                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18448                     int user = mSettings.mPreferredActivities.keyAt(i);
18449                     if (pir.dump(pw,
18450                             dumpState.getTitlePrinted()
18451                                 ? "\nPreferred Activities User " + user + ":"
18452                                 : "Preferred Activities User " + user + ":", "  ",
18453                             packageName, true, false)) {
18454                         dumpState.setTitlePrinted(true);
18455                     }
18456                 }
18457             }
18458 
18459             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
18460                 pw.flush();
18461                 FileOutputStream fout = new FileOutputStream(fd);
18462                 BufferedOutputStream str = new BufferedOutputStream(fout);
18463                 XmlSerializer serializer = new FastXmlSerializer();
18464                 try {
18465                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
18466                     serializer.startDocument(null, true);
18467                     serializer.setFeature(
18468                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
18469                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
18470                     serializer.endDocument();
18471                     serializer.flush();
18472                 } catch (IllegalArgumentException e) {
18473                     pw.println("Failed writing: " + e);
18474                 } catch (IllegalStateException e) {
18475                     pw.println("Failed writing: " + e);
18476                 } catch (IOException e) {
18477                     pw.println("Failed writing: " + e);
18478                 }
18479             }
18480 
18481             if (!checkin
18482                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
18483                     && packageName == null) {
18484                 pw.println();
18485                 int count = mSettings.mPackages.size();
18486                 if (count == 0) {
18487                     pw.println("No applications!");
18488                     pw.println();
18489                 } else {
18490                     final String prefix = "  ";
18491                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
18492                     if (allPackageSettings.size() == 0) {
18493                         pw.println("No domain preferred apps!");
18494                         pw.println();
18495                     } else {
18496                         pw.println("App verification status:");
18497                         pw.println();
18498                         count = 0;
18499                         for (PackageSetting ps : allPackageSettings) {
18500                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
18501                             if (ivi == null || ivi.getPackageName() == null) continue;
18502                             pw.println(prefix + "Package: " + ivi.getPackageName());
18503                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
18504                             pw.println(prefix + "Status:  " + ivi.getStatusString());
18505                             pw.println();
18506                             count++;
18507                         }
18508                         if (count == 0) {
18509                             pw.println(prefix + "No app verification established.");
18510                             pw.println();
18511                         }
18512                         for (int userId : sUserManager.getUserIds()) {
18513                             pw.println("App linkages for user " + userId + ":");
18514                             pw.println();
18515                             count = 0;
18516                             for (PackageSetting ps : allPackageSettings) {
18517                                 final long status = ps.getDomainVerificationStatusForUser(userId);
18518                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
18519                                     continue;
18520                                 }
18521                                 pw.println(prefix + "Package: " + ps.name);
18522                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
18523                                 String statusStr = IntentFilterVerificationInfo.
18524                                         getStatusStringFromValue(status);
18525                                 pw.println(prefix + "Status:  " + statusStr);
18526                                 pw.println();
18527                                 count++;
18528                             }
18529                             if (count == 0) {
18530                                 pw.println(prefix + "No configured app linkages.");
18531                                 pw.println();
18532                             }
18533                         }
18534                     }
18535                 }
18536             }
18537 
18538             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
18539                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
18540                 if (packageName == null && permissionNames == null) {
18541                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
18542                         if (iperm == 0) {
18543                             if (dumpState.onTitlePrinted())
18544                                 pw.println();
18545                             pw.println("AppOp Permissions:");
18546                         }
18547                         pw.print("  AppOp Permission ");
18548                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
18549                         pw.println(":");
18550                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
18551                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
18552                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
18553                         }
18554                     }
18555                 }
18556             }
18557 
18558             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
18559                 boolean printedSomething = false;
18560                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
18561                     if (packageName != null && !packageName.equals(p.info.packageName)) {
18562                         continue;
18563                     }
18564                     if (!printedSomething) {
18565                         if (dumpState.onTitlePrinted())
18566                             pw.println();
18567                         pw.println("Registered ContentProviders:");
18568                         printedSomething = true;
18569                     }
18570                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
18571                     pw.print("    "); pw.println(p.toString());
18572                 }
18573                 printedSomething = false;
18574                 for (Map.Entry<String, PackageParser.Provider> entry :
18575                         mProvidersByAuthority.entrySet()) {
18576                     PackageParser.Provider p = entry.getValue();
18577                     if (packageName != null && !packageName.equals(p.info.packageName)) {
18578                         continue;
18579                     }
18580                     if (!printedSomething) {
18581                         if (dumpState.onTitlePrinted())
18582                             pw.println();
18583                         pw.println("ContentProvider Authorities:");
18584                         printedSomething = true;
18585                     }
18586                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
18587                     pw.print("    "); pw.println(p.toString());
18588                     if (p.info != null && p.info.applicationInfo != null) {
18589                         final String appInfo = p.info.applicationInfo.toString();
18590                         pw.print("      applicationInfo="); pw.println(appInfo);
18591                     }
18592                 }
18593             }
18594 
18595             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
18596                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
18597             }
18598 
18599             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
18600                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
18601             }
18602 
18603             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
18604                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
18605             }
18606 
18607             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
18608                 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
18609             }
18610 
18611             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
18612                 // XXX should handle packageName != null by dumping only install data that
18613                 // the given package is involved with.
18614                 if (dumpState.onTitlePrinted()) pw.println();
18615                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
18616             }
18617 
18618             if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
18619                 // XXX should handle packageName != null by dumping only install data that
18620                 // the given package is involved with.
18621                 if (dumpState.onTitlePrinted()) pw.println();
18622 
18623                 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
18624                 ipw.println();
18625                 ipw.println("Frozen packages:");
18626                 ipw.increaseIndent();
18627                 if (mFrozenPackages.size() == 0) {
18628                     ipw.println("(none)");
18629                 } else {
18630                     for (int i = 0; i < mFrozenPackages.size(); i++) {
18631                         ipw.println(mFrozenPackages.valueAt(i));
18632                     }
18633                 }
18634                 ipw.decreaseIndent();
18635             }
18636 
18637             if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
18638                 if (dumpState.onTitlePrinted()) pw.println();
18639                 dumpDexoptStateLPr(pw, packageName);
18640             }
18641 
18642             if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
18643                 if (dumpState.onTitlePrinted()) pw.println();
18644                 dumpCompilerStatsLPr(pw, packageName);
18645             }
18646 
18647             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
18648                 if (dumpState.onTitlePrinted()) pw.println();
18649                 mSettings.dumpReadMessagesLPr(pw, dumpState);
18650 
18651                 pw.println();
18652                 pw.println("Package warning messages:");
18653                 BufferedReader in = null;
18654                 String line = null;
18655                 try {
18656                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
18657                     while ((line = in.readLine()) != null) {
18658                         if (line.contains("ignored: updated version")) continue;
18659                         pw.println(line);
18660                     }
18661                 } catch (IOException ignored) {
18662                 } finally {
18663                     IoUtils.closeQuietly(in);
18664                 }
18665             }
18666 
18667             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
18668                 BufferedReader in = null;
18669                 String line = null;
18670                 try {
18671                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
18672                     while ((line = in.readLine()) != null) {
18673                         if (line.contains("ignored: updated version")) continue;
18674                         pw.print("msg,");
18675                         pw.println(line);
18676                     }
18677                 } catch (IOException ignored) {
18678                 } finally {
18679                     IoUtils.closeQuietly(in);
18680                 }
18681             }
18682         }
18683     }
18684 
dumpDexoptStateLPr(PrintWriter pw, String packageName)18685     private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
18686         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
18687         ipw.println();
18688         ipw.println("Dexopt state:");
18689         ipw.increaseIndent();
18690         Collection<PackageParser.Package> packages = null;
18691         if (packageName != null) {
18692             PackageParser.Package targetPackage = mPackages.get(packageName);
18693             if (targetPackage != null) {
18694                 packages = Collections.singletonList(targetPackage);
18695             } else {
18696                 ipw.println("Unable to find package: " + packageName);
18697                 return;
18698             }
18699         } else {
18700             packages = mPackages.values();
18701         }
18702 
18703         for (PackageParser.Package pkg : packages) {
18704             ipw.println("[" + pkg.packageName + "]");
18705             ipw.increaseIndent();
18706             mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
18707             ipw.decreaseIndent();
18708         }
18709     }
18710 
dumpCompilerStatsLPr(PrintWriter pw, String packageName)18711     private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
18712         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
18713         ipw.println();
18714         ipw.println("Compiler stats:");
18715         ipw.increaseIndent();
18716         Collection<PackageParser.Package> packages = null;
18717         if (packageName != null) {
18718             PackageParser.Package targetPackage = mPackages.get(packageName);
18719             if (targetPackage != null) {
18720                 packages = Collections.singletonList(targetPackage);
18721             } else {
18722                 ipw.println("Unable to find package: " + packageName);
18723                 return;
18724             }
18725         } else {
18726             packages = mPackages.values();
18727         }
18728 
18729         for (PackageParser.Package pkg : packages) {
18730             ipw.println("[" + pkg.packageName + "]");
18731             ipw.increaseIndent();
18732 
18733             CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
18734             if (stats == null) {
18735                 ipw.println("(No recorded stats)");
18736             } else {
18737                 stats.dump(ipw);
18738             }
18739             ipw.decreaseIndent();
18740         }
18741     }
18742 
dumpDomainString(String packageName)18743     private String dumpDomainString(String packageName) {
18744         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
18745                 .getList();
18746         List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
18747 
18748         ArraySet<String> result = new ArraySet<>();
18749         if (iviList.size() > 0) {
18750             for (IntentFilterVerificationInfo ivi : iviList) {
18751                 for (String host : ivi.getDomains()) {
18752                     result.add(host);
18753                 }
18754             }
18755         }
18756         if (filters != null && filters.size() > 0) {
18757             for (IntentFilter filter : filters) {
18758                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
18759                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
18760                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
18761                     result.addAll(filter.getHostsList());
18762                 }
18763             }
18764         }
18765 
18766         StringBuilder sb = new StringBuilder(result.size() * 16);
18767         for (String domain : result) {
18768             if (sb.length() > 0) sb.append(" ");
18769             sb.append(domain);
18770         }
18771         return sb.toString();
18772     }
18773 
18774     // ------- apps on sdcard specific code -------
18775     static final boolean DEBUG_SD_INSTALL = false;
18776 
18777     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
18778 
18779     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
18780 
18781     private boolean mMediaMounted = false;
18782 
getEncryptKey()18783     static String getEncryptKey() {
18784         try {
18785             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
18786                     SD_ENCRYPTION_KEYSTORE_NAME);
18787             if (sdEncKey == null) {
18788                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
18789                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
18790                 if (sdEncKey == null) {
18791                     Slog.e(TAG, "Failed to create encryption keys");
18792                     return null;
18793                 }
18794             }
18795             return sdEncKey;
18796         } catch (NoSuchAlgorithmException nsae) {
18797             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
18798             return null;
18799         } catch (IOException ioe) {
18800             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
18801             return null;
18802         }
18803     }
18804 
18805     /*
18806      * Update media status on PackageManager.
18807      */
18808     @Override
updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)18809     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
18810         int callingUid = Binder.getCallingUid();
18811         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
18812             throw new SecurityException("Media status can only be updated by the system");
18813         }
18814         // reader; this apparently protects mMediaMounted, but should probably
18815         // be a different lock in that case.
18816         synchronized (mPackages) {
18817             Log.i(TAG, "Updating external media status from "
18818                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
18819                     + (mediaStatus ? "mounted" : "unmounted"));
18820             if (DEBUG_SD_INSTALL)
18821                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
18822                         + ", mMediaMounted=" + mMediaMounted);
18823             if (mediaStatus == mMediaMounted) {
18824                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
18825                         : 0, -1);
18826                 mHandler.sendMessage(msg);
18827                 return;
18828             }
18829             mMediaMounted = mediaStatus;
18830         }
18831         // Queue up an async operation since the package installation may take a
18832         // little while.
18833         mHandler.post(new Runnable() {
18834             public void run() {
18835                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
18836             }
18837         });
18838     }
18839 
18840     /**
18841      * Called by MountService when the initial ASECs to scan are available.
18842      * Should block until all the ASEC containers are finished being scanned.
18843      */
scanAvailableAsecs()18844     public void scanAvailableAsecs() {
18845         updateExternalMediaStatusInner(true, false, false);
18846     }
18847 
18848     /*
18849      * Collect information of applications on external media, map them against
18850      * existing containers and update information based on current mount status.
18851      * Please note that we always have to report status if reportStatus has been
18852      * set to true especially when unloading packages.
18853      */
updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)18854     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
18855             boolean externalStorage) {
18856         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
18857         int[] uidArr = EmptyArray.INT;
18858 
18859         final String[] list = PackageHelper.getSecureContainerList();
18860         if (ArrayUtils.isEmpty(list)) {
18861             Log.i(TAG, "No secure containers found");
18862         } else {
18863             // Process list of secure containers and categorize them
18864             // as active or stale based on their package internal state.
18865 
18866             // reader
18867             synchronized (mPackages) {
18868                 for (String cid : list) {
18869                     // Leave stages untouched for now; installer service owns them
18870                     if (PackageInstallerService.isStageName(cid)) continue;
18871 
18872                     if (DEBUG_SD_INSTALL)
18873                         Log.i(TAG, "Processing container " + cid);
18874                     String pkgName = getAsecPackageName(cid);
18875                     if (pkgName == null) {
18876                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
18877                         continue;
18878                     }
18879                     if (DEBUG_SD_INSTALL)
18880                         Log.i(TAG, "Looking for pkg : " + pkgName);
18881 
18882                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
18883                     if (ps == null) {
18884                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
18885                         continue;
18886                     }
18887 
18888                     /*
18889                      * Skip packages that are not external if we're unmounting
18890                      * external storage.
18891                      */
18892                     if (externalStorage && !isMounted && !isExternal(ps)) {
18893                         continue;
18894                     }
18895 
18896                     final AsecInstallArgs args = new AsecInstallArgs(cid,
18897                             getAppDexInstructionSets(ps), ps.isForwardLocked());
18898                     // The package status is changed only if the code path
18899                     // matches between settings and the container id.
18900                     if (ps.codePathString != null
18901                             && ps.codePathString.startsWith(args.getCodePath())) {
18902                         if (DEBUG_SD_INSTALL) {
18903                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
18904                                     + " at code path: " + ps.codePathString);
18905                         }
18906 
18907                         // We do have a valid package installed on sdcard
18908                         processCids.put(args, ps.codePathString);
18909                         final int uid = ps.appId;
18910                         if (uid != -1) {
18911                             uidArr = ArrayUtils.appendInt(uidArr, uid);
18912                         }
18913                     } else {
18914                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
18915                                 + ps.codePathString);
18916                     }
18917                 }
18918             }
18919 
18920             Arrays.sort(uidArr);
18921         }
18922 
18923         // Process packages with valid entries.
18924         if (isMounted) {
18925             if (DEBUG_SD_INSTALL)
18926                 Log.i(TAG, "Loading packages");
18927             loadMediaPackages(processCids, uidArr, externalStorage);
18928             startCleaningPackages();
18929             mInstallerService.onSecureContainersAvailable();
18930         } else {
18931             if (DEBUG_SD_INSTALL)
18932                 Log.i(TAG, "Unloading packages");
18933             unloadMediaPackages(processCids, uidArr, reportStatus);
18934         }
18935     }
18936 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver)18937     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
18938             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
18939         final int size = infos.size();
18940         final String[] packageNames = new String[size];
18941         final int[] packageUids = new int[size];
18942         for (int i = 0; i < size; i++) {
18943             final ApplicationInfo info = infos.get(i);
18944             packageNames[i] = info.packageName;
18945             packageUids[i] = info.uid;
18946         }
18947         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
18948                 finishedReceiver);
18949     }
18950 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)18951     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
18952             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
18953         sendResourcesChangedBroadcast(mediaStatus, replacing,
18954                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
18955     }
18956 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver)18957     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
18958             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
18959         int size = pkgList.length;
18960         if (size > 0) {
18961             // Send broadcasts here
18962             Bundle extras = new Bundle();
18963             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
18964             if (uidArr != null) {
18965                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
18966             }
18967             if (replacing) {
18968                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
18969             }
18970             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
18971                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
18972             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
18973         }
18974     }
18975 
18976    /*
18977      * Look at potentially valid container ids from processCids If package
18978      * information doesn't match the one on record or package scanning fails,
18979      * the cid is added to list of removeCids. We currently don't delete stale
18980      * containers.
18981      */
loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, boolean externalStorage)18982     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
18983             boolean externalStorage) {
18984         ArrayList<String> pkgList = new ArrayList<String>();
18985         Set<AsecInstallArgs> keys = processCids.keySet();
18986 
18987         for (AsecInstallArgs args : keys) {
18988             String codePath = processCids.get(args);
18989             if (DEBUG_SD_INSTALL)
18990                 Log.i(TAG, "Loading container : " + args.cid);
18991             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
18992             try {
18993                 // Make sure there are no container errors first.
18994                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
18995                     Slog.e(TAG, "Failed to mount cid : " + args.cid
18996                             + " when installing from sdcard");
18997                     continue;
18998                 }
18999                 // Check code path here.
19000                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
19001                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
19002                             + " does not match one in settings " + codePath);
19003                     continue;
19004                 }
19005                 // Parse package
19006                 int parseFlags = mDefParseFlags;
19007                 if (args.isExternalAsec()) {
19008                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
19009                 }
19010                 if (args.isFwdLocked()) {
19011                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
19012                 }
19013 
19014                 synchronized (mInstallLock) {
19015                     PackageParser.Package pkg = null;
19016                     try {
19017                         // Sadly we don't know the package name yet to freeze it
19018                         pkg = scanPackageTracedLI(new File(codePath), parseFlags,
19019                                 SCAN_IGNORE_FROZEN, 0, null);
19020                     } catch (PackageManagerException e) {
19021                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
19022                     }
19023                     // Scan the package
19024                     if (pkg != null) {
19025                         /*
19026                          * TODO why is the lock being held? doPostInstall is
19027                          * called in other places without the lock. This needs
19028                          * to be straightened out.
19029                          */
19030                         // writer
19031                         synchronized (mPackages) {
19032                             retCode = PackageManager.INSTALL_SUCCEEDED;
19033                             pkgList.add(pkg.packageName);
19034                             // Post process args
19035                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
19036                                     pkg.applicationInfo.uid);
19037                         }
19038                     } else {
19039                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
19040                     }
19041                 }
19042 
19043             } finally {
19044                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
19045                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
19046                 }
19047             }
19048         }
19049         // writer
19050         synchronized (mPackages) {
19051             // If the platform SDK has changed since the last time we booted,
19052             // we need to re-grant app permission to catch any new ones that
19053             // appear. This is really a hack, and means that apps can in some
19054             // cases get permissions that the user didn't initially explicitly
19055             // allow... it would be nice to have some better way to handle
19056             // this situation.
19057             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
19058                     : mSettings.getInternalVersion();
19059             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
19060                     : StorageManager.UUID_PRIVATE_INTERNAL;
19061 
19062             int updateFlags = UPDATE_PERMISSIONS_ALL;
19063             if (ver.sdkVersion != mSdkVersion) {
19064                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19065                         + mSdkVersion + "; regranting permissions for external");
19066                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19067             }
19068             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19069 
19070             // Yay, everything is now upgraded
19071             ver.forceCurrent();
19072 
19073             // can downgrade to reader
19074             // Persist settings
19075             mSettings.writeLPr();
19076         }
19077         // Send a broadcast to let everyone know we are done processing
19078         if (pkgList.size() > 0) {
19079             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
19080         }
19081     }
19082 
19083    /*
19084      * Utility method to unload a list of specified containers
19085      */
unloadAllContainers(Set<AsecInstallArgs> cidArgs)19086     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
19087         // Just unmount all valid containers.
19088         for (AsecInstallArgs arg : cidArgs) {
19089             synchronized (mInstallLock) {
19090                 arg.doPostDeleteLI(false);
19091            }
19092        }
19093    }
19094 
19095     /*
19096      * Unload packages mounted on external media. This involves deleting package
19097      * data from internal structures, sending broadcasts about disabled packages,
19098      * gc'ing to free up references, unmounting all secure containers
19099      * corresponding to packages on external media, and posting a
19100      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
19101      * that we always have to post this message if status has been requested no
19102      * matter what.
19103      */
unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)19104     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
19105             final boolean reportStatus) {
19106         if (DEBUG_SD_INSTALL)
19107             Log.i(TAG, "unloading media packages");
19108         ArrayList<String> pkgList = new ArrayList<String>();
19109         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
19110         final Set<AsecInstallArgs> keys = processCids.keySet();
19111         for (AsecInstallArgs args : keys) {
19112             String pkgName = args.getPackageName();
19113             if (DEBUG_SD_INSTALL)
19114                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
19115             // Delete package internally
19116             PackageRemovedInfo outInfo = new PackageRemovedInfo();
19117             synchronized (mInstallLock) {
19118                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19119                 final boolean res;
19120                 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
19121                         "unloadMediaPackages")) {
19122                     res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
19123                             null);
19124                 }
19125                 if (res) {
19126                     pkgList.add(pkgName);
19127                 } else {
19128                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
19129                     failedList.add(args);
19130                 }
19131             }
19132         }
19133 
19134         // reader
19135         synchronized (mPackages) {
19136             // We didn't update the settings after removing each package;
19137             // write them now for all packages.
19138             mSettings.writeLPr();
19139         }
19140 
19141         // We have to absolutely send UPDATED_MEDIA_STATUS only
19142         // after confirming that all the receivers processed the ordered
19143         // broadcast when packages get disabled, force a gc to clean things up.
19144         // and unload all the containers.
19145         if (pkgList.size() > 0) {
19146             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
19147                     new IIntentReceiver.Stub() {
19148                 public void performReceive(Intent intent, int resultCode, String data,
19149                         Bundle extras, boolean ordered, boolean sticky,
19150                         int sendingUser) throws RemoteException {
19151                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
19152                             reportStatus ? 1 : 0, 1, keys);
19153                     mHandler.sendMessage(msg);
19154                 }
19155             });
19156         } else {
19157             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
19158                     keys);
19159             mHandler.sendMessage(msg);
19160         }
19161     }
19162 
loadPrivatePackages(final VolumeInfo vol)19163     private void loadPrivatePackages(final VolumeInfo vol) {
19164         mHandler.post(new Runnable() {
19165             @Override
19166             public void run() {
19167                 loadPrivatePackagesInner(vol);
19168             }
19169         });
19170     }
19171 
loadPrivatePackagesInner(VolumeInfo vol)19172     private void loadPrivatePackagesInner(VolumeInfo vol) {
19173         final String volumeUuid = vol.fsUuid;
19174         if (TextUtils.isEmpty(volumeUuid)) {
19175             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
19176             return;
19177         }
19178 
19179         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
19180         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
19181         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
19182 
19183         final VersionInfo ver;
19184         final List<PackageSetting> packages;
19185         synchronized (mPackages) {
19186             ver = mSettings.findOrCreateVersion(volumeUuid);
19187             packages = mSettings.getVolumePackagesLPr(volumeUuid);
19188         }
19189 
19190         for (PackageSetting ps : packages) {
19191             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
19192             synchronized (mInstallLock) {
19193                 final PackageParser.Package pkg;
19194                 try {
19195                     pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
19196                     loaded.add(pkg.applicationInfo);
19197 
19198                 } catch (PackageManagerException e) {
19199                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
19200                 }
19201 
19202                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
19203                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
19204                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
19205                                     | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19206                 }
19207             }
19208         }
19209 
19210         // Reconcile app data for all started/unlocked users
19211         final StorageManager sm = mContext.getSystemService(StorageManager.class);
19212         final UserManager um = mContext.getSystemService(UserManager.class);
19213         UserManagerInternal umInternal = getUserManagerInternal();
19214         for (UserInfo user : um.getUsers()) {
19215             final int flags;
19216             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
19217                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19218             } else if (umInternal.isUserRunning(user.id)) {
19219                 flags = StorageManager.FLAG_STORAGE_DE;
19220             } else {
19221                 continue;
19222             }
19223 
19224             try {
19225                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
19226                 synchronized (mInstallLock) {
19227                     reconcileAppsDataLI(volumeUuid, user.id, flags);
19228                 }
19229             } catch (IllegalStateException e) {
19230                 // Device was probably ejected, and we'll process that event momentarily
19231                 Slog.w(TAG, "Failed to prepare storage: " + e);
19232             }
19233         }
19234 
19235         synchronized (mPackages) {
19236             int updateFlags = UPDATE_PERMISSIONS_ALL;
19237             if (ver.sdkVersion != mSdkVersion) {
19238                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19239                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
19240                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19241             }
19242             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19243 
19244             // Yay, everything is now upgraded
19245             ver.forceCurrent();
19246 
19247             mSettings.writeLPr();
19248         }
19249 
19250         for (PackageFreezer freezer : freezers) {
19251             freezer.close();
19252         }
19253 
19254         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
19255         sendResourcesChangedBroadcast(true, false, loaded, null);
19256     }
19257 
unloadPrivatePackages(final VolumeInfo vol)19258     private void unloadPrivatePackages(final VolumeInfo vol) {
19259         mHandler.post(new Runnable() {
19260             @Override
19261             public void run() {
19262                 unloadPrivatePackagesInner(vol);
19263             }
19264         });
19265     }
19266 
unloadPrivatePackagesInner(VolumeInfo vol)19267     private void unloadPrivatePackagesInner(VolumeInfo vol) {
19268         final String volumeUuid = vol.fsUuid;
19269         if (TextUtils.isEmpty(volumeUuid)) {
19270             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
19271             return;
19272         }
19273 
19274         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
19275         synchronized (mInstallLock) {
19276         synchronized (mPackages) {
19277             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
19278             for (PackageSetting ps : packages) {
19279                 if (ps.pkg == null) continue;
19280 
19281                 final ApplicationInfo info = ps.pkg.applicationInfo;
19282                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19283                 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
19284 
19285                 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
19286                         "unloadPrivatePackagesInner")) {
19287                     if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
19288                             false, null)) {
19289                         unloaded.add(info);
19290                     } else {
19291                         Slog.w(TAG, "Failed to unload " + ps.codePath);
19292                     }
19293                 }
19294 
19295                 // Try very hard to release any references to this package
19296                 // so we don't risk the system server being killed due to
19297                 // open FDs
19298                 AttributeCache.instance().removePackage(ps.name);
19299             }
19300 
19301             mSettings.writeLPr();
19302         }
19303         }
19304 
19305         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
19306         sendResourcesChangedBroadcast(false, false, unloaded, null);
19307 
19308         // Try very hard to release any references to this path so we don't risk
19309         // the system server being killed due to open FDs
19310         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
19311 
19312         for (int i = 0; i < 3; i++) {
19313             System.gc();
19314             System.runFinalization();
19315         }
19316     }
19317 
19318     /**
19319      * Prepare storage areas for given user on all mounted devices.
19320      */
prepareUserData(int userId, int userSerial, int flags)19321     void prepareUserData(int userId, int userSerial, int flags) {
19322         synchronized (mInstallLock) {
19323             final StorageManager storage = mContext.getSystemService(StorageManager.class);
19324             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19325                 final String volumeUuid = vol.getFsUuid();
19326                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
19327             }
19328         }
19329     }
19330 
prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, boolean allowRecover)19331     private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags,
19332             boolean allowRecover) {
19333         // Prepare storage and verify that serial numbers are consistent; if
19334         // there's a mismatch we need to destroy to avoid leaking data
19335         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19336         try {
19337             storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
19338 
19339             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
19340                 UserManagerService.enforceSerialNumber(
19341                         Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
19342                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19343                     UserManagerService.enforceSerialNumber(
19344                             Environment.getDataSystemDeDirectory(userId), userSerial);
19345                 }
19346             }
19347             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
19348                 UserManagerService.enforceSerialNumber(
19349                         Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
19350                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19351                     UserManagerService.enforceSerialNumber(
19352                             Environment.getDataSystemCeDirectory(userId), userSerial);
19353                 }
19354             }
19355 
19356             synchronized (mInstallLock) {
19357                 mInstaller.createUserData(volumeUuid, userId, userSerial, flags);
19358             }
19359         } catch (Exception e) {
19360             logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid
19361                     + " because we failed to prepare: " + e);
19362             destroyUserDataLI(volumeUuid, userId,
19363                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19364 
19365             if (allowRecover) {
19366                 // Try one last time; if we fail again we're really in trouble
19367                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false);
19368             }
19369         }
19370     }
19371 
19372     /**
19373      * Destroy storage areas for given user on all mounted devices.
19374      */
destroyUserData(int userId, int flags)19375     void destroyUserData(int userId, int flags) {
19376         synchronized (mInstallLock) {
19377             final StorageManager storage = mContext.getSystemService(StorageManager.class);
19378             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19379                 final String volumeUuid = vol.getFsUuid();
19380                 destroyUserDataLI(volumeUuid, userId, flags);
19381             }
19382         }
19383     }
19384 
destroyUserDataLI(String volumeUuid, int userId, int flags)19385     private void destroyUserDataLI(String volumeUuid, int userId, int flags) {
19386         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19387         try {
19388             // Clean up app data, profile data, and media data
19389             mInstaller.destroyUserData(volumeUuid, userId, flags);
19390 
19391             // Clean up system data
19392             if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19393                 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19394                     FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
19395                     FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
19396                 }
19397                 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19398                     FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
19399                 }
19400             }
19401 
19402             // Data with special labels is now gone, so finish the job
19403             storage.destroyUserStorage(volumeUuid, userId, flags);
19404 
19405         } catch (Exception e) {
19406             logCriticalInfo(Log.WARN,
19407                     "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e);
19408         }
19409     }
19410 
19411     /**
19412      * Examine all users present on given mounted volume, and destroy data
19413      * belonging to users that are no longer valid, or whose user ID has been
19414      * recycled.
19415      */
reconcileUsers(String volumeUuid)19416     private void reconcileUsers(String volumeUuid) {
19417         final List<File> files = new ArrayList<>();
19418         Collections.addAll(files, FileUtils
19419                 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
19420         Collections.addAll(files, FileUtils
19421                 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
19422         Collections.addAll(files, FileUtils
19423                 .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
19424         Collections.addAll(files, FileUtils
19425                 .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
19426         for (File file : files) {
19427             if (!file.isDirectory()) continue;
19428 
19429             final int userId;
19430             final UserInfo info;
19431             try {
19432                 userId = Integer.parseInt(file.getName());
19433                 info = sUserManager.getUserInfo(userId);
19434             } catch (NumberFormatException e) {
19435                 Slog.w(TAG, "Invalid user directory " + file);
19436                 continue;
19437             }
19438 
19439             boolean destroyUser = false;
19440             if (info == null) {
19441                 logCriticalInfo(Log.WARN, "Destroying user directory " + file
19442                         + " because no matching user was found");
19443                 destroyUser = true;
19444             } else if (!mOnlyCore) {
19445                 try {
19446                     UserManagerService.enforceSerialNumber(file, info.serialNumber);
19447                 } catch (IOException e) {
19448                     logCriticalInfo(Log.WARN, "Destroying user directory " + file
19449                             + " because we failed to enforce serial number: " + e);
19450                     destroyUser = true;
19451                 }
19452             }
19453 
19454             if (destroyUser) {
19455                 synchronized (mInstallLock) {
19456                     destroyUserDataLI(volumeUuid, userId,
19457                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19458                 }
19459             }
19460         }
19461     }
19462 
assertPackageKnown(String volumeUuid, String packageName)19463     private void assertPackageKnown(String volumeUuid, String packageName)
19464             throws PackageManagerException {
19465         synchronized (mPackages) {
19466             final PackageSetting ps = mSettings.mPackages.get(packageName);
19467             if (ps == null) {
19468                 throw new PackageManagerException("Package " + packageName + " is unknown");
19469             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19470                 throw new PackageManagerException(
19471                         "Package " + packageName + " found on unknown volume " + volumeUuid
19472                                 + "; expected volume " + ps.volumeUuid);
19473             }
19474         }
19475     }
19476 
assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)19477     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
19478             throws PackageManagerException {
19479         synchronized (mPackages) {
19480             final PackageSetting ps = mSettings.mPackages.get(packageName);
19481             if (ps == null) {
19482                 throw new PackageManagerException("Package " + packageName + " is unknown");
19483             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19484                 throw new PackageManagerException(
19485                         "Package " + packageName + " found on unknown volume " + volumeUuid
19486                                 + "; expected volume " + ps.volumeUuid);
19487             } else if (!ps.getInstalled(userId)) {
19488                 throw new PackageManagerException(
19489                         "Package " + packageName + " not installed for user " + userId);
19490             }
19491         }
19492     }
19493 
19494     /**
19495      * Examine all apps present on given mounted volume, and destroy apps that
19496      * aren't expected, either due to uninstallation or reinstallation on
19497      * another volume.
19498      */
reconcileApps(String volumeUuid)19499     private void reconcileApps(String volumeUuid) {
19500         final File[] files = FileUtils
19501                 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
19502         for (File file : files) {
19503             final boolean isPackage = (isApkFile(file) || file.isDirectory())
19504                     && !PackageInstallerService.isStageName(file.getName());
19505             if (!isPackage) {
19506                 // Ignore entries which are not packages
19507                 continue;
19508             }
19509 
19510             try {
19511                 final PackageLite pkg = PackageParser.parsePackageLite(file,
19512                         PackageParser.PARSE_MUST_BE_APK);
19513                 assertPackageKnown(volumeUuid, pkg.packageName);
19514 
19515             } catch (PackageParserException | PackageManagerException e) {
19516                 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19517                 synchronized (mInstallLock) {
19518                     removeCodePathLI(file);
19519                 }
19520             }
19521         }
19522     }
19523 
19524     /**
19525      * Reconcile all app data for the given user.
19526      * <p>
19527      * Verifies that directories exist and that ownership and labeling is
19528      * correct for all installed apps on all mounted volumes.
19529      */
reconcileAppsData(int userId, int flags)19530     void reconcileAppsData(int userId, int flags) {
19531         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19532         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19533             final String volumeUuid = vol.getFsUuid();
19534             synchronized (mInstallLock) {
19535                 reconcileAppsDataLI(volumeUuid, userId, flags);
19536             }
19537         }
19538     }
19539 
19540     /**
19541      * Reconcile all app data on given mounted volume.
19542      * <p>
19543      * Destroys app data that isn't expected, either due to uninstallation or
19544      * reinstallation on another volume.
19545      * <p>
19546      * Verifies that directories exist and that ownership and labeling is
19547      * correct for all installed apps.
19548      */
reconcileAppsDataLI(String volumeUuid, int userId, int flags)19549     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) {
19550         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
19551                 + Integer.toHexString(flags));
19552 
19553         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
19554         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
19555 
19556         boolean restoreconNeeded = false;
19557 
19558         // First look for stale data that doesn't belong, and check if things
19559         // have changed since we did our last restorecon
19560         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19561             if (StorageManager.isFileEncryptedNativeOrEmulated()
19562                     && !StorageManager.isUserKeyUnlocked(userId)) {
19563                 throw new RuntimeException(
19564                         "Yikes, someone asked us to reconcile CE storage while " + userId
19565                                 + " was still locked; this would have caused massive data loss!");
19566             }
19567 
19568             restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir);
19569 
19570             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
19571             for (File file : files) {
19572                 final String packageName = file.getName();
19573                 try {
19574                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
19575                 } catch (PackageManagerException e) {
19576                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19577                     try {
19578                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
19579                                 StorageManager.FLAG_STORAGE_CE, 0);
19580                     } catch (InstallerException e2) {
19581                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
19582                     }
19583                 }
19584             }
19585         }
19586         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19587             restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir);
19588 
19589             final File[] files = FileUtils.listFilesOrEmpty(deDir);
19590             for (File file : files) {
19591                 final String packageName = file.getName();
19592                 try {
19593                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
19594                 } catch (PackageManagerException e) {
19595                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19596                     try {
19597                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
19598                                 StorageManager.FLAG_STORAGE_DE, 0);
19599                     } catch (InstallerException e2) {
19600                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
19601                     }
19602                 }
19603             }
19604         }
19605 
19606         // Ensure that data directories are ready to roll for all packages
19607         // installed for this volume and user
19608         final List<PackageSetting> packages;
19609         synchronized (mPackages) {
19610             packages = mSettings.getVolumePackagesLPr(volumeUuid);
19611         }
19612         int preparedCount = 0;
19613         for (PackageSetting ps : packages) {
19614             final String packageName = ps.name;
19615             if (ps.pkg == null) {
19616                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
19617                 // TODO: might be due to legacy ASEC apps; we should circle back
19618                 // and reconcile again once they're scanned
19619                 continue;
19620             }
19621 
19622             if (ps.getInstalled(userId)) {
19623                 prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded);
19624 
19625                 if (maybeMigrateAppDataLIF(ps.pkg, userId)) {
19626                     // We may have just shuffled around app data directories, so
19627                     // prepare them one more time
19628                     prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded);
19629                 }
19630 
19631                 preparedCount++;
19632             }
19633         }
19634 
19635         if (restoreconNeeded) {
19636             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19637                 SELinuxMMAC.setRestoreconDone(ceDir);
19638             }
19639             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19640                 SELinuxMMAC.setRestoreconDone(deDir);
19641             }
19642         }
19643 
19644         Slog.v(TAG, "reconcileAppsData finished " + preparedCount
19645                 + " packages; restoreconNeeded was " + restoreconNeeded);
19646     }
19647 
19648     /**
19649      * Prepare app data for the given app just after it was installed or
19650      * upgraded. This method carefully only touches users that it's installed
19651      * for, and it forces a restorecon to handle any seinfo changes.
19652      * <p>
19653      * Verifies that directories exist and that ownership and labeling is
19654      * correct for all installed apps. If there is an ownership mismatch, it
19655      * will try recovering system apps by wiping data; third-party app data is
19656      * left intact.
19657      * <p>
19658      * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
19659      */
prepareAppDataAfterInstallLIF(PackageParser.Package pkg)19660     private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
19661         final PackageSetting ps;
19662         synchronized (mPackages) {
19663             ps = mSettings.mPackages.get(pkg.packageName);
19664             mSettings.writeKernelMappingLPr(ps);
19665         }
19666 
19667         final UserManager um = mContext.getSystemService(UserManager.class);
19668         UserManagerInternal umInternal = getUserManagerInternal();
19669         for (UserInfo user : um.getUsers()) {
19670             final int flags;
19671             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
19672                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19673             } else if (umInternal.isUserRunning(user.id)) {
19674                 flags = StorageManager.FLAG_STORAGE_DE;
19675             } else {
19676                 continue;
19677             }
19678 
19679             if (ps.getInstalled(user.id)) {
19680                 // Whenever an app changes, force a restorecon of its data
19681                 // TODO: when user data is locked, mark that we're still dirty
19682                 prepareAppDataLIF(pkg, user.id, flags, true);
19683             }
19684         }
19685     }
19686 
19687     /**
19688      * Prepare app data for the given app.
19689      * <p>
19690      * Verifies that directories exist and that ownership and labeling is
19691      * correct for all installed apps. If there is an ownership mismatch, this
19692      * will try recovering system apps by wiping data; third-party app data is
19693      * left intact.
19694      */
prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded)19695     private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags,
19696             boolean restoreconNeeded) {
19697         if (pkg == null) {
19698             Slog.wtf(TAG, "Package was null!", new Throwable());
19699             return;
19700         }
19701         prepareAppDataLeafLIF(pkg, userId, flags, restoreconNeeded);
19702         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
19703         for (int i = 0; i < childCount; i++) {
19704             prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags, restoreconNeeded);
19705         }
19706     }
19707 
prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded)19708     private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags,
19709             boolean restoreconNeeded) {
19710         if (DEBUG_APP_DATA) {
19711             Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
19712                     + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : ""));
19713         }
19714 
19715         final String volumeUuid = pkg.volumeUuid;
19716         final String packageName = pkg.packageName;
19717         final ApplicationInfo app = pkg.applicationInfo;
19718         final int appId = UserHandle.getAppId(app.uid);
19719 
19720         Preconditions.checkNotNull(app.seinfo);
19721 
19722         try {
19723             mInstaller.createAppData(volumeUuid, packageName, userId, flags,
19724                     appId, app.seinfo, app.targetSdkVersion);
19725         } catch (InstallerException e) {
19726             if (app.isSystemApp()) {
19727                 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
19728                         + ", but trying to recover: " + e);
19729                 destroyAppDataLeafLIF(pkg, userId, flags);
19730                 try {
19731                     mInstaller.createAppData(volumeUuid, packageName, userId, flags,
19732                             appId, app.seinfo, app.targetSdkVersion);
19733                     logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
19734                 } catch (InstallerException e2) {
19735                     logCriticalInfo(Log.DEBUG, "Recovery failed!");
19736                 }
19737             } else {
19738                 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
19739             }
19740         }
19741 
19742         if (restoreconNeeded) {
19743             try {
19744                 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId,
19745                         app.seinfo);
19746             } catch (InstallerException e) {
19747                 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e);
19748             }
19749         }
19750 
19751         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19752             try {
19753                 // CE storage is unlocked right now, so read out the inode and
19754                 // remember for use later when it's locked
19755                 // TODO: mark this structure as dirty so we persist it!
19756                 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId,
19757                         StorageManager.FLAG_STORAGE_CE);
19758                 synchronized (mPackages) {
19759                     final PackageSetting ps = mSettings.mPackages.get(packageName);
19760                     if (ps != null) {
19761                         ps.setCeDataInode(ceDataInode, userId);
19762                     }
19763                 }
19764             } catch (InstallerException e) {
19765                 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e);
19766             }
19767         }
19768 
19769         prepareAppDataContentsLeafLIF(pkg, userId, flags);
19770     }
19771 
prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags)19772     private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
19773         if (pkg == null) {
19774             Slog.wtf(TAG, "Package was null!", new Throwable());
19775             return;
19776         }
19777         prepareAppDataContentsLeafLIF(pkg, userId, flags);
19778         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
19779         for (int i = 0; i < childCount; i++) {
19780             prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
19781         }
19782     }
19783 
prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags)19784     private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
19785         final String volumeUuid = pkg.volumeUuid;
19786         final String packageName = pkg.packageName;
19787         final ApplicationInfo app = pkg.applicationInfo;
19788 
19789         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19790             // Create a native library symlink only if we have native libraries
19791             // and if the native libraries are 32 bit libraries. We do not provide
19792             // this symlink for 64 bit libraries.
19793             if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
19794                 final String nativeLibPath = app.nativeLibraryDir;
19795                 try {
19796                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
19797                             nativeLibPath, userId);
19798                 } catch (InstallerException e) {
19799                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
19800                 }
19801             }
19802         }
19803     }
19804 
19805     /**
19806      * For system apps on non-FBE devices, this method migrates any existing
19807      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
19808      * requested by the app.
19809      */
maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId)19810     private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
19811         if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
19812                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
19813             final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
19814                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
19815             try {
19816                 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
19817                         storageTarget);
19818             } catch (InstallerException e) {
19819                 logCriticalInfo(Log.WARN,
19820                         "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
19821             }
19822             return true;
19823         } else {
19824             return false;
19825         }
19826     }
19827 
freezePackage(String packageName, String killReason)19828     public PackageFreezer freezePackage(String packageName, String killReason) {
19829         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
19830     }
19831 
freezePackage(String packageName, int userId, String killReason)19832     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
19833         return new PackageFreezer(packageName, userId, killReason);
19834     }
19835 
freezePackageForInstall(String packageName, int installFlags, String killReason)19836     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
19837             String killReason) {
19838         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
19839     }
19840 
freezePackageForInstall(String packageName, int userId, int installFlags, String killReason)19841     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
19842             String killReason) {
19843         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
19844             return new PackageFreezer();
19845         } else {
19846             return freezePackage(packageName, userId, killReason);
19847         }
19848     }
19849 
freezePackageForDelete(String packageName, int deleteFlags, String killReason)19850     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
19851             String killReason) {
19852         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
19853     }
19854 
freezePackageForDelete(String packageName, int userId, int deleteFlags, String killReason)19855     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
19856             String killReason) {
19857         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
19858             return new PackageFreezer();
19859         } else {
19860             return freezePackage(packageName, userId, killReason);
19861         }
19862     }
19863 
19864     /**
19865      * Class that freezes and kills the given package upon creation, and
19866      * unfreezes it upon closing. This is typically used when doing surgery on
19867      * app code/data to prevent the app from running while you're working.
19868      */
19869     private class PackageFreezer implements AutoCloseable {
19870         private final String mPackageName;
19871         private final PackageFreezer[] mChildren;
19872 
19873         private final boolean mWeFroze;
19874 
19875         private final AtomicBoolean mClosed = new AtomicBoolean();
19876         private final CloseGuard mCloseGuard = CloseGuard.get();
19877 
19878         /**
19879          * Create and return a stub freezer that doesn't actually do anything,
19880          * typically used when someone requested
19881          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
19882          * {@link PackageManager#DELETE_DONT_KILL_APP}.
19883          */
PackageFreezer()19884         public PackageFreezer() {
19885             mPackageName = null;
19886             mChildren = null;
19887             mWeFroze = false;
19888             mCloseGuard.open("close");
19889         }
19890 
PackageFreezer(String packageName, int userId, String killReason)19891         public PackageFreezer(String packageName, int userId, String killReason) {
19892             synchronized (mPackages) {
19893                 mPackageName = packageName;
19894                 mWeFroze = mFrozenPackages.add(mPackageName);
19895 
19896                 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
19897                 if (ps != null) {
19898                     killApplication(ps.name, ps.appId, userId, killReason);
19899                 }
19900 
19901                 final PackageParser.Package p = mPackages.get(packageName);
19902                 if (p != null && p.childPackages != null) {
19903                     final int N = p.childPackages.size();
19904                     mChildren = new PackageFreezer[N];
19905                     for (int i = 0; i < N; i++) {
19906                         mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
19907                                 userId, killReason);
19908                     }
19909                 } else {
19910                     mChildren = null;
19911                 }
19912             }
19913             mCloseGuard.open("close");
19914         }
19915 
19916         @Override
finalize()19917         protected void finalize() throws Throwable {
19918             try {
19919                 mCloseGuard.warnIfOpen();
19920                 close();
19921             } finally {
19922                 super.finalize();
19923             }
19924         }
19925 
19926         @Override
close()19927         public void close() {
19928             mCloseGuard.close();
19929             if (mClosed.compareAndSet(false, true)) {
19930                 synchronized (mPackages) {
19931                     if (mWeFroze) {
19932                         mFrozenPackages.remove(mPackageName);
19933                     }
19934 
19935                     if (mChildren != null) {
19936                         for (PackageFreezer freezer : mChildren) {
19937                             freezer.close();
19938                         }
19939                     }
19940                 }
19941             }
19942         }
19943     }
19944 
19945     /**
19946      * Verify that given package is currently frozen.
19947      */
checkPackageFrozen(String packageName)19948     private void checkPackageFrozen(String packageName) {
19949         synchronized (mPackages) {
19950             if (!mFrozenPackages.contains(packageName)) {
19951                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
19952             }
19953         }
19954     }
19955 
19956     @Override
movePackage(final String packageName, final String volumeUuid)19957     public int movePackage(final String packageName, final String volumeUuid) {
19958         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
19959 
19960         final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
19961         final int moveId = mNextMoveId.getAndIncrement();
19962         mHandler.post(new Runnable() {
19963             @Override
19964             public void run() {
19965                 try {
19966                     movePackageInternal(packageName, volumeUuid, moveId, user);
19967                 } catch (PackageManagerException e) {
19968                     Slog.w(TAG, "Failed to move " + packageName, e);
19969                     mMoveCallbacks.notifyStatusChanged(moveId,
19970                             PackageManager.MOVE_FAILED_INTERNAL_ERROR);
19971                 }
19972             }
19973         });
19974         return moveId;
19975     }
19976 
movePackageInternal(final String packageName, final String volumeUuid, final int moveId, UserHandle user)19977     private void movePackageInternal(final String packageName, final String volumeUuid,
19978             final int moveId, UserHandle user) throws PackageManagerException {
19979         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19980         final PackageManager pm = mContext.getPackageManager();
19981 
19982         final boolean currentAsec;
19983         final String currentVolumeUuid;
19984         final File codeFile;
19985         final String installerPackageName;
19986         final String packageAbiOverride;
19987         final int appId;
19988         final String seinfo;
19989         final String label;
19990         final int targetSdkVersion;
19991         final PackageFreezer freezer;
19992         final int[] installedUserIds;
19993 
19994         // reader
19995         synchronized (mPackages) {
19996             final PackageParser.Package pkg = mPackages.get(packageName);
19997             final PackageSetting ps = mSettings.mPackages.get(packageName);
19998             if (pkg == null || ps == null) {
19999                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
20000             }
20001 
20002             if (pkg.applicationInfo.isSystemApp()) {
20003                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
20004                         "Cannot move system application");
20005             }
20006 
20007             if (pkg.applicationInfo.isExternalAsec()) {
20008                 currentAsec = true;
20009                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
20010             } else if (pkg.applicationInfo.isForwardLocked()) {
20011                 currentAsec = true;
20012                 currentVolumeUuid = "forward_locked";
20013             } else {
20014                 currentAsec = false;
20015                 currentVolumeUuid = ps.volumeUuid;
20016 
20017                 final File probe = new File(pkg.codePath);
20018                 final File probeOat = new File(probe, "oat");
20019                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
20020                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20021                             "Move only supported for modern cluster style installs");
20022                 }
20023             }
20024 
20025             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
20026                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20027                         "Package already moved to " + volumeUuid);
20028             }
20029             if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
20030                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
20031                         "Device admin cannot be moved");
20032             }
20033 
20034             if (mFrozenPackages.contains(packageName)) {
20035                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
20036                         "Failed to move already frozen package");
20037             }
20038 
20039             codeFile = new File(pkg.codePath);
20040             installerPackageName = ps.installerPackageName;
20041             packageAbiOverride = ps.cpuAbiOverrideString;
20042             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20043             seinfo = pkg.applicationInfo.seinfo;
20044             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
20045             targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
20046             freezer = freezePackage(packageName, "movePackageInternal");
20047             installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
20048         }
20049 
20050         final Bundle extras = new Bundle();
20051         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
20052         extras.putString(Intent.EXTRA_TITLE, label);
20053         mMoveCallbacks.notifyCreated(moveId, extras);
20054 
20055         int installFlags;
20056         final boolean moveCompleteApp;
20057         final File measurePath;
20058 
20059         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
20060             installFlags = INSTALL_INTERNAL;
20061             moveCompleteApp = !currentAsec;
20062             measurePath = Environment.getDataAppDirectory(volumeUuid);
20063         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
20064             installFlags = INSTALL_EXTERNAL;
20065             moveCompleteApp = false;
20066             measurePath = storage.getPrimaryPhysicalVolume().getPath();
20067         } else {
20068             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
20069             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
20070                     || !volume.isMountedWritable()) {
20071                 freezer.close();
20072                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20073                         "Move location not mounted private volume");
20074             }
20075 
20076             Preconditions.checkState(!currentAsec);
20077 
20078             installFlags = INSTALL_INTERNAL;
20079             moveCompleteApp = true;
20080             measurePath = Environment.getDataAppDirectory(volumeUuid);
20081         }
20082 
20083         final PackageStats stats = new PackageStats(null, -1);
20084         synchronized (mInstaller) {
20085             for (int userId : installedUserIds) {
20086                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
20087                     freezer.close();
20088                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20089                             "Failed to measure package size");
20090                 }
20091             }
20092         }
20093 
20094         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
20095                 + stats.dataSize);
20096 
20097         final long startFreeBytes = measurePath.getFreeSpace();
20098         final long sizeBytes;
20099         if (moveCompleteApp) {
20100             sizeBytes = stats.codeSize + stats.dataSize;
20101         } else {
20102             sizeBytes = stats.codeSize;
20103         }
20104 
20105         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
20106             freezer.close();
20107             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20108                     "Not enough free space to move");
20109         }
20110 
20111         mMoveCallbacks.notifyStatusChanged(moveId, 10);
20112 
20113         final CountDownLatch installedLatch = new CountDownLatch(1);
20114         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
20115             @Override
20116             public void onUserActionRequired(Intent intent) throws RemoteException {
20117                 throw new IllegalStateException();
20118             }
20119 
20120             @Override
20121             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
20122                     Bundle extras) throws RemoteException {
20123                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
20124                         + PackageManager.installStatusToString(returnCode, msg));
20125 
20126                 installedLatch.countDown();
20127                 freezer.close();
20128 
20129                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
20130                 switch (status) {
20131                     case PackageInstaller.STATUS_SUCCESS:
20132                         mMoveCallbacks.notifyStatusChanged(moveId,
20133                                 PackageManager.MOVE_SUCCEEDED);
20134                         break;
20135                     case PackageInstaller.STATUS_FAILURE_STORAGE:
20136                         mMoveCallbacks.notifyStatusChanged(moveId,
20137                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
20138                         break;
20139                     default:
20140                         mMoveCallbacks.notifyStatusChanged(moveId,
20141                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
20142                         break;
20143                 }
20144             }
20145         };
20146 
20147         final MoveInfo move;
20148         if (moveCompleteApp) {
20149             // Kick off a thread to report progress estimates
20150             new Thread() {
20151                 @Override
20152                 public void run() {
20153                     while (true) {
20154                         try {
20155                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
20156                                 break;
20157                             }
20158                         } catch (InterruptedException ignored) {
20159                         }
20160 
20161                         final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
20162                         final int progress = 10 + (int) MathUtils.constrain(
20163                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
20164                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
20165                     }
20166                 }
20167             }.start();
20168 
20169             final String dataAppName = codeFile.getName();
20170             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
20171                     dataAppName, appId, seinfo, targetSdkVersion);
20172         } else {
20173             move = null;
20174         }
20175 
20176         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
20177 
20178         final Message msg = mHandler.obtainMessage(INIT_COPY);
20179         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
20180         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
20181                 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
20182                 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/);
20183         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
20184         msg.obj = params;
20185 
20186         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
20187                 System.identityHashCode(msg.obj));
20188         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
20189                 System.identityHashCode(msg.obj));
20190 
20191         mHandler.sendMessage(msg);
20192     }
20193 
20194     @Override
movePrimaryStorage(String volumeUuid)20195     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
20196         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
20197 
20198         final int realMoveId = mNextMoveId.getAndIncrement();
20199         final Bundle extras = new Bundle();
20200         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
20201         mMoveCallbacks.notifyCreated(realMoveId, extras);
20202 
20203         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
20204             @Override
20205             public void onCreated(int moveId, Bundle extras) {
20206                 // Ignored
20207             }
20208 
20209             @Override
20210             public void onStatusChanged(int moveId, int status, long estMillis) {
20211                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
20212             }
20213         };
20214 
20215         final StorageManager storage = mContext.getSystemService(StorageManager.class);
20216         storage.setPrimaryStorageUuid(volumeUuid, callback);
20217         return realMoveId;
20218     }
20219 
20220     @Override
getMoveStatus(int moveId)20221     public int getMoveStatus(int moveId) {
20222         mContext.enforceCallingOrSelfPermission(
20223                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20224         return mMoveCallbacks.mLastStatus.get(moveId);
20225     }
20226 
20227     @Override
registerMoveCallback(IPackageMoveObserver callback)20228     public void registerMoveCallback(IPackageMoveObserver callback) {
20229         mContext.enforceCallingOrSelfPermission(
20230                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20231         mMoveCallbacks.register(callback);
20232     }
20233 
20234     @Override
unregisterMoveCallback(IPackageMoveObserver callback)20235     public void unregisterMoveCallback(IPackageMoveObserver callback) {
20236         mContext.enforceCallingOrSelfPermission(
20237                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20238         mMoveCallbacks.unregister(callback);
20239     }
20240 
20241     @Override
setInstallLocation(int loc)20242     public boolean setInstallLocation(int loc) {
20243         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
20244                 null);
20245         if (getInstallLocation() == loc) {
20246             return true;
20247         }
20248         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
20249                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
20250             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
20251                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
20252             return true;
20253         }
20254         return false;
20255    }
20256 
20257     @Override
getInstallLocation()20258     public int getInstallLocation() {
20259         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
20260                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
20261                 PackageHelper.APP_INSTALL_AUTO);
20262     }
20263 
20264     /** Called by UserManagerService */
cleanUpUser(UserManagerService userManager, int userHandle)20265     void cleanUpUser(UserManagerService userManager, int userHandle) {
20266         synchronized (mPackages) {
20267             mDirtyUsers.remove(userHandle);
20268             mUserNeedsBadging.delete(userHandle);
20269             mSettings.removeUserLPw(userHandle);
20270             mPendingBroadcasts.remove(userHandle);
20271             mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
20272             removeUnusedPackagesLPw(userManager, userHandle);
20273         }
20274     }
20275 
20276     /**
20277      * We're removing userHandle and would like to remove any downloaded packages
20278      * that are no longer in use by any other user.
20279      * @param userHandle the user being removed
20280      */
removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle)20281     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
20282         final boolean DEBUG_CLEAN_APKS = false;
20283         int [] users = userManager.getUserIds();
20284         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
20285         while (psit.hasNext()) {
20286             PackageSetting ps = psit.next();
20287             if (ps.pkg == null) {
20288                 continue;
20289             }
20290             final String packageName = ps.pkg.packageName;
20291             // Skip over if system app
20292             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
20293                 continue;
20294             }
20295             if (DEBUG_CLEAN_APKS) {
20296                 Slog.i(TAG, "Checking package " + packageName);
20297             }
20298             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
20299             if (keep) {
20300                 if (DEBUG_CLEAN_APKS) {
20301                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
20302                 }
20303             } else {
20304                 for (int i = 0; i < users.length; i++) {
20305                     if (users[i] != userHandle && ps.getInstalled(users[i])) {
20306                         keep = true;
20307                         if (DEBUG_CLEAN_APKS) {
20308                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
20309                                     + users[i]);
20310                         }
20311                         break;
20312                     }
20313                 }
20314             }
20315             if (!keep) {
20316                 if (DEBUG_CLEAN_APKS) {
20317                     Slog.i(TAG, "  Removing package " + packageName);
20318                 }
20319                 mHandler.post(new Runnable() {
20320                     public void run() {
20321                         deletePackageX(packageName, userHandle, 0);
20322                     } //end run
20323                 });
20324             }
20325         }
20326     }
20327 
20328     /** Called by UserManagerService */
createNewUser(int userId)20329     void createNewUser(int userId) {
20330         synchronized (mInstallLock) {
20331             mSettings.createNewUserLI(this, mInstaller, userId);
20332         }
20333         synchronized (mPackages) {
20334             scheduleWritePackageRestrictionsLocked(userId);
20335             scheduleWritePackageListLocked(userId);
20336             applyFactoryDefaultBrowserLPw(userId);
20337             primeDomainVerificationsLPw(userId);
20338         }
20339     }
20340 
onNewUserCreated(final int userId)20341     void onNewUserCreated(final int userId) {
20342         mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20343         // If permission review for legacy apps is required, we represent
20344         // dagerous permissions for such apps as always granted runtime
20345         // permissions to keep per user flag state whether review is needed.
20346         // Hence, if a new user is added we have to propagate dangerous
20347         // permission grants for these legacy apps.
20348         if (Build.PERMISSIONS_REVIEW_REQUIRED) {
20349             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
20350                     | UPDATE_PERMISSIONS_REPLACE_ALL);
20351         }
20352     }
20353 
20354     @Override
getVerifierDeviceIdentity()20355     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
20356         mContext.enforceCallingOrSelfPermission(
20357                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
20358                 "Only package verification agents can read the verifier device identity");
20359 
20360         synchronized (mPackages) {
20361             return mSettings.getVerifierDeviceIdentityLPw();
20362         }
20363     }
20364 
20365     @Override
setPermissionEnforced(String permission, boolean enforced)20366     public void setPermissionEnforced(String permission, boolean enforced) {
20367         // TODO: Now that we no longer change GID for storage, this should to away.
20368         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
20369                 "setPermissionEnforced");
20370         if (READ_EXTERNAL_STORAGE.equals(permission)) {
20371             synchronized (mPackages) {
20372                 if (mSettings.mReadExternalStorageEnforced == null
20373                         || mSettings.mReadExternalStorageEnforced != enforced) {
20374                     mSettings.mReadExternalStorageEnforced = enforced;
20375                     mSettings.writeLPr();
20376                 }
20377             }
20378             // kill any non-foreground processes so we restart them and
20379             // grant/revoke the GID.
20380             final IActivityManager am = ActivityManagerNative.getDefault();
20381             if (am != null) {
20382                 final long token = Binder.clearCallingIdentity();
20383                 try {
20384                     am.killProcessesBelowForeground("setPermissionEnforcement");
20385                 } catch (RemoteException e) {
20386                 } finally {
20387                     Binder.restoreCallingIdentity(token);
20388                 }
20389             }
20390         } else {
20391             throw new IllegalArgumentException("No selective enforcement for " + permission);
20392         }
20393     }
20394 
20395     @Override
20396     @Deprecated
isPermissionEnforced(String permission)20397     public boolean isPermissionEnforced(String permission) {
20398         return true;
20399     }
20400 
20401     @Override
isStorageLow()20402     public boolean isStorageLow() {
20403         final long token = Binder.clearCallingIdentity();
20404         try {
20405             final DeviceStorageMonitorInternal
20406                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
20407             if (dsm != null) {
20408                 return dsm.isMemoryLow();
20409             } else {
20410                 return false;
20411             }
20412         } finally {
20413             Binder.restoreCallingIdentity(token);
20414         }
20415     }
20416 
20417     @Override
getPackageInstaller()20418     public IPackageInstaller getPackageInstaller() {
20419         return mInstallerService;
20420     }
20421 
userNeedsBadging(int userId)20422     private boolean userNeedsBadging(int userId) {
20423         int index = mUserNeedsBadging.indexOfKey(userId);
20424         if (index < 0) {
20425             final UserInfo userInfo;
20426             final long token = Binder.clearCallingIdentity();
20427             try {
20428                 userInfo = sUserManager.getUserInfo(userId);
20429             } finally {
20430                 Binder.restoreCallingIdentity(token);
20431             }
20432             final boolean b;
20433             if (userInfo != null && userInfo.isManagedProfile()) {
20434                 b = true;
20435             } else {
20436                 b = false;
20437             }
20438             mUserNeedsBadging.put(userId, b);
20439             return b;
20440         }
20441         return mUserNeedsBadging.valueAt(index);
20442     }
20443 
20444     @Override
getKeySetByAlias(String packageName, String alias)20445     public KeySet getKeySetByAlias(String packageName, String alias) {
20446         if (packageName == null || alias == null) {
20447             return null;
20448         }
20449         synchronized(mPackages) {
20450             final PackageParser.Package pkg = mPackages.get(packageName);
20451             if (pkg == null) {
20452                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20453                 throw new IllegalArgumentException("Unknown package: " + packageName);
20454             }
20455             KeySetManagerService ksms = mSettings.mKeySetManagerService;
20456             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
20457         }
20458     }
20459 
20460     @Override
getSigningKeySet(String packageName)20461     public KeySet getSigningKeySet(String packageName) {
20462         if (packageName == null) {
20463             return null;
20464         }
20465         synchronized(mPackages) {
20466             final PackageParser.Package pkg = mPackages.get(packageName);
20467             if (pkg == null) {
20468                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20469                 throw new IllegalArgumentException("Unknown package: " + packageName);
20470             }
20471             if (pkg.applicationInfo.uid != Binder.getCallingUid()
20472                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
20473                 throw new SecurityException("May not access signing KeySet of other apps.");
20474             }
20475             KeySetManagerService ksms = mSettings.mKeySetManagerService;
20476             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
20477         }
20478     }
20479 
20480     @Override
isPackageSignedByKeySet(String packageName, KeySet ks)20481     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
20482         if (packageName == null || ks == null) {
20483             return false;
20484         }
20485         synchronized(mPackages) {
20486             final PackageParser.Package pkg = mPackages.get(packageName);
20487             if (pkg == null) {
20488                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20489                 throw new IllegalArgumentException("Unknown package: " + packageName);
20490             }
20491             IBinder ksh = ks.getToken();
20492             if (ksh instanceof KeySetHandle) {
20493                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
20494                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
20495             }
20496             return false;
20497         }
20498     }
20499 
20500     @Override
isPackageSignedByKeySetExactly(String packageName, KeySet ks)20501     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
20502         if (packageName == null || ks == null) {
20503             return false;
20504         }
20505         synchronized(mPackages) {
20506             final PackageParser.Package pkg = mPackages.get(packageName);
20507             if (pkg == null) {
20508                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20509                 throw new IllegalArgumentException("Unknown package: " + packageName);
20510             }
20511             IBinder ksh = ks.getToken();
20512             if (ksh instanceof KeySetHandle) {
20513                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
20514                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
20515             }
20516             return false;
20517         }
20518     }
20519 
deletePackageIfUnusedLPr(final String packageName)20520     private void deletePackageIfUnusedLPr(final String packageName) {
20521         PackageSetting ps = mSettings.mPackages.get(packageName);
20522         if (ps == null) {
20523             return;
20524         }
20525         if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
20526             // TODO Implement atomic delete if package is unused
20527             // It is currently possible that the package will be deleted even if it is installed
20528             // after this method returns.
20529             mHandler.post(new Runnable() {
20530                 public void run() {
20531                     deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
20532                 }
20533             });
20534         }
20535     }
20536 
20537     /**
20538      * Check and throw if the given before/after packages would be considered a
20539      * downgrade.
20540      */
checkDowngrade(PackageParser.Package before, PackageInfoLite after)20541     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
20542             throws PackageManagerException {
20543         if (after.versionCode < before.mVersionCode) {
20544             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20545                     "Update version code " + after.versionCode + " is older than current "
20546                     + before.mVersionCode);
20547         } else if (after.versionCode == before.mVersionCode) {
20548             if (after.baseRevisionCode < before.baseRevisionCode) {
20549                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20550                         "Update base revision code " + after.baseRevisionCode
20551                         + " is older than current " + before.baseRevisionCode);
20552             }
20553 
20554             if (!ArrayUtils.isEmpty(after.splitNames)) {
20555                 for (int i = 0; i < after.splitNames.length; i++) {
20556                     final String splitName = after.splitNames[i];
20557                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
20558                     if (j != -1) {
20559                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
20560                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20561                                     "Update split " + splitName + " revision code "
20562                                     + after.splitRevisionCodes[i] + " is older than current "
20563                                     + before.splitRevisionCodes[j]);
20564                         }
20565                     }
20566                 }
20567             }
20568         }
20569     }
20570 
20571     private static class MoveCallbacks extends Handler {
20572         private static final int MSG_CREATED = 1;
20573         private static final int MSG_STATUS_CHANGED = 2;
20574 
20575         private final RemoteCallbackList<IPackageMoveObserver>
20576                 mCallbacks = new RemoteCallbackList<>();
20577 
20578         private final SparseIntArray mLastStatus = new SparseIntArray();
20579 
MoveCallbacks(Looper looper)20580         public MoveCallbacks(Looper looper) {
20581             super(looper);
20582         }
20583 
register(IPackageMoveObserver callback)20584         public void register(IPackageMoveObserver callback) {
20585             mCallbacks.register(callback);
20586         }
20587 
unregister(IPackageMoveObserver callback)20588         public void unregister(IPackageMoveObserver callback) {
20589             mCallbacks.unregister(callback);
20590         }
20591 
20592         @Override
handleMessage(Message msg)20593         public void handleMessage(Message msg) {
20594             final SomeArgs args = (SomeArgs) msg.obj;
20595             final int n = mCallbacks.beginBroadcast();
20596             for (int i = 0; i < n; i++) {
20597                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
20598                 try {
20599                     invokeCallback(callback, msg.what, args);
20600                 } catch (RemoteException ignored) {
20601                 }
20602             }
20603             mCallbacks.finishBroadcast();
20604             args.recycle();
20605         }
20606 
invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)20607         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
20608                 throws RemoteException {
20609             switch (what) {
20610                 case MSG_CREATED: {
20611                     callback.onCreated(args.argi1, (Bundle) args.arg2);
20612                     break;
20613                 }
20614                 case MSG_STATUS_CHANGED: {
20615                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
20616                     break;
20617                 }
20618             }
20619         }
20620 
notifyCreated(int moveId, Bundle extras)20621         private void notifyCreated(int moveId, Bundle extras) {
20622             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
20623 
20624             final SomeArgs args = SomeArgs.obtain();
20625             args.argi1 = moveId;
20626             args.arg2 = extras;
20627             obtainMessage(MSG_CREATED, args).sendToTarget();
20628         }
20629 
notifyStatusChanged(int moveId, int status)20630         private void notifyStatusChanged(int moveId, int status) {
20631             notifyStatusChanged(moveId, status, -1);
20632         }
20633 
notifyStatusChanged(int moveId, int status, long estMillis)20634         private void notifyStatusChanged(int moveId, int status, long estMillis) {
20635             Slog.v(TAG, "Move " + moveId + " status " + status);
20636 
20637             final SomeArgs args = SomeArgs.obtain();
20638             args.argi1 = moveId;
20639             args.argi2 = status;
20640             args.arg3 = estMillis;
20641             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
20642 
20643             synchronized (mLastStatus) {
20644                 mLastStatus.put(moveId, status);
20645             }
20646         }
20647     }
20648 
20649     private final static class OnPermissionChangeListeners extends Handler {
20650         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
20651 
20652         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
20653                 new RemoteCallbackList<>();
20654 
OnPermissionChangeListeners(Looper looper)20655         public OnPermissionChangeListeners(Looper looper) {
20656             super(looper);
20657         }
20658 
20659         @Override
handleMessage(Message msg)20660         public void handleMessage(Message msg) {
20661             switch (msg.what) {
20662                 case MSG_ON_PERMISSIONS_CHANGED: {
20663                     final int uid = msg.arg1;
20664                     handleOnPermissionsChanged(uid);
20665                 } break;
20666             }
20667         }
20668 
addListenerLocked(IOnPermissionsChangeListener listener)20669         public void addListenerLocked(IOnPermissionsChangeListener listener) {
20670             mPermissionListeners.register(listener);
20671 
20672         }
20673 
removeListenerLocked(IOnPermissionsChangeListener listener)20674         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
20675             mPermissionListeners.unregister(listener);
20676         }
20677 
onPermissionsChanged(int uid)20678         public void onPermissionsChanged(int uid) {
20679             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
20680                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
20681             }
20682         }
20683 
handleOnPermissionsChanged(int uid)20684         private void handleOnPermissionsChanged(int uid) {
20685             final int count = mPermissionListeners.beginBroadcast();
20686             try {
20687                 for (int i = 0; i < count; i++) {
20688                     IOnPermissionsChangeListener callback = mPermissionListeners
20689                             .getBroadcastItem(i);
20690                     try {
20691                         callback.onPermissionsChanged(uid);
20692                     } catch (RemoteException e) {
20693                         Log.e(TAG, "Permission listener is dead", e);
20694                     }
20695                 }
20696             } finally {
20697                 mPermissionListeners.finishBroadcast();
20698             }
20699         }
20700     }
20701 
20702     private class PackageManagerInternalImpl extends PackageManagerInternal {
20703         @Override
setLocationPackagesProvider(PackagesProvider provider)20704         public void setLocationPackagesProvider(PackagesProvider provider) {
20705             synchronized (mPackages) {
20706                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
20707             }
20708         }
20709 
20710         @Override
setVoiceInteractionPackagesProvider(PackagesProvider provider)20711         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
20712             synchronized (mPackages) {
20713                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
20714             }
20715         }
20716 
20717         @Override
setSmsAppPackagesProvider(PackagesProvider provider)20718         public void setSmsAppPackagesProvider(PackagesProvider provider) {
20719             synchronized (mPackages) {
20720                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
20721             }
20722         }
20723 
20724         @Override
setDialerAppPackagesProvider(PackagesProvider provider)20725         public void setDialerAppPackagesProvider(PackagesProvider provider) {
20726             synchronized (mPackages) {
20727                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
20728             }
20729         }
20730 
20731         @Override
setSimCallManagerPackagesProvider(PackagesProvider provider)20732         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
20733             synchronized (mPackages) {
20734                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
20735             }
20736         }
20737 
20738         @Override
setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider)20739         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
20740             synchronized (mPackages) {
20741                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
20742             }
20743         }
20744 
20745         @Override
grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId)20746         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
20747             synchronized (mPackages) {
20748                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
20749                         packageName, userId);
20750             }
20751         }
20752 
20753         @Override
grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId)20754         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
20755             synchronized (mPackages) {
20756                 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
20757                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
20758                         packageName, userId);
20759             }
20760         }
20761 
20762         @Override
grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId)20763         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
20764             synchronized (mPackages) {
20765                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
20766                         packageName, userId);
20767             }
20768         }
20769 
20770         @Override
setKeepUninstalledPackages(final List<String> packageList)20771         public void setKeepUninstalledPackages(final List<String> packageList) {
20772             Preconditions.checkNotNull(packageList);
20773             List<String> removedFromList = null;
20774             synchronized (mPackages) {
20775                 if (mKeepUninstalledPackages != null) {
20776                     final int packagesCount = mKeepUninstalledPackages.size();
20777                     for (int i = 0; i < packagesCount; i++) {
20778                         String oldPackage = mKeepUninstalledPackages.get(i);
20779                         if (packageList != null && packageList.contains(oldPackage)) {
20780                             continue;
20781                         }
20782                         if (removedFromList == null) {
20783                             removedFromList = new ArrayList<>();
20784                         }
20785                         removedFromList.add(oldPackage);
20786                     }
20787                 }
20788                 mKeepUninstalledPackages = new ArrayList<>(packageList);
20789                 if (removedFromList != null) {
20790                     final int removedCount = removedFromList.size();
20791                     for (int i = 0; i < removedCount; i++) {
20792                         deletePackageIfUnusedLPr(removedFromList.get(i));
20793                     }
20794                 }
20795             }
20796         }
20797 
20798         @Override
isPermissionsReviewRequired(String packageName, int userId)20799         public boolean isPermissionsReviewRequired(String packageName, int userId) {
20800             synchronized (mPackages) {
20801                 // If we do not support permission review, done.
20802                 if (!Build.PERMISSIONS_REVIEW_REQUIRED) {
20803                     return false;
20804                 }
20805 
20806                 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
20807                 if (packageSetting == null) {
20808                     return false;
20809                 }
20810 
20811                 // Permission review applies only to apps not supporting the new permission model.
20812                 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
20813                     return false;
20814                 }
20815 
20816                 // Legacy apps have the permission and get user consent on launch.
20817                 PermissionsState permissionsState = packageSetting.getPermissionsState();
20818                 return permissionsState.isPermissionReviewRequired(userId);
20819             }
20820         }
20821 
20822         @Override
getApplicationInfo(String packageName, int userId)20823         public ApplicationInfo getApplicationInfo(String packageName, int userId) {
20824             return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
20825         }
20826 
20827         @Override
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)20828         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20829                 int userId) {
20830             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
20831         }
20832 
20833         @Override
setDeviceAndProfileOwnerPackages( int deviceOwnerUserId, String deviceOwnerPackage, SparseArray<String> profileOwnerPackages)20834         public void setDeviceAndProfileOwnerPackages(
20835                 int deviceOwnerUserId, String deviceOwnerPackage,
20836                 SparseArray<String> profileOwnerPackages) {
20837             mProtectedPackages.setDeviceAndProfileOwnerPackages(
20838                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
20839         }
20840 
20841         @Override
isPackageDataProtected(int userId, String packageName)20842         public boolean isPackageDataProtected(int userId, String packageName) {
20843             return mProtectedPackages.isPackageDataProtected(userId, packageName);
20844         }
20845     }
20846 
20847     @Override
grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId)20848     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
20849         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
20850         synchronized (mPackages) {
20851             final long identity = Binder.clearCallingIdentity();
20852             try {
20853                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
20854                         packageNames, userId);
20855             } finally {
20856                 Binder.restoreCallingIdentity(identity);
20857             }
20858         }
20859     }
20860 
enforceSystemOrPhoneCaller(String tag)20861     private static void enforceSystemOrPhoneCaller(String tag) {
20862         int callingUid = Binder.getCallingUid();
20863         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
20864             throw new SecurityException(
20865                     "Cannot call " + tag + " from UID " + callingUid);
20866         }
20867     }
20868 
isHistoricalPackageUsageAvailable()20869     boolean isHistoricalPackageUsageAvailable() {
20870         return mPackageUsage.isHistoricalPackageUsageAvailable();
20871     }
20872 
20873     /**
20874      * Return a <b>copy</b> of the collection of packages known to the package manager.
20875      * @return A copy of the values of mPackages.
20876      */
getPackages()20877     Collection<PackageParser.Package> getPackages() {
20878         synchronized (mPackages) {
20879             return new ArrayList<>(mPackages.values());
20880         }
20881     }
20882 
20883     /**
20884      * Logs process start information (including base APK hash) to the security log.
20885      * @hide
20886      */
logAppProcessStartIfNeeded(String processName, int uid, String seinfo, String apkFile, int pid)20887     public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
20888             String apkFile, int pid) {
20889         if (!SecurityLog.isLoggingEnabled()) {
20890             return;
20891         }
20892         Bundle data = new Bundle();
20893         data.putLong("startTimestamp", System.currentTimeMillis());
20894         data.putString("processName", processName);
20895         data.putInt("uid", uid);
20896         data.putString("seinfo", seinfo);
20897         data.putString("apkFile", apkFile);
20898         data.putInt("pid", pid);
20899         Message msg = mProcessLoggingHandler.obtainMessage(
20900                 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
20901         msg.setData(data);
20902         mProcessLoggingHandler.sendMessage(msg);
20903     }
20904 
getCompilerPackageStats(String pkgName)20905     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
20906         return mCompilerStats.getPackageStats(pkgName);
20907     }
20908 
getOrCreateCompilerPackageStats(PackageParser.Package pkg)20909     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
20910         return getOrCreateCompilerPackageStats(pkg.packageName);
20911     }
20912 
getOrCreateCompilerPackageStats(String pkgName)20913     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
20914         return mCompilerStats.getOrCreatePackageStats(pkgName);
20915     }
20916 
deleteCompilerPackageStats(String pkgName)20917     public void deleteCompilerPackageStats(String pkgName) {
20918         mCompilerStats.deletePackageStats(pkgName);
20919     }
20920 }
20921