• 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.DELETE_PACKAGES;
20 import static android.Manifest.permission.INSTALL_PACKAGES;
21 import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23 import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
24 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25 import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
53 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
54 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
55 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
56 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
57 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
58 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
59 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66 import static android.content.pm.PackageManager.MATCH_ALL;
67 import static android.content.pm.PackageManager.MATCH_ANY_USER;
68 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76 import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80 import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83 import static android.content.pm.PackageManager.PERMISSION_DENIED;
84 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
86 import static android.content.pm.PackageParser.isApkFile;
87 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
88 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
89 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
90 import static android.system.OsConstants.O_CREAT;
91 import static android.system.OsConstants.O_RDWR;
92 
93 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
94 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
95 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
96 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
97 import static com.android.internal.util.ArrayUtils.appendInt;
98 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
99 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
100 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
101 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
102 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
103 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
104 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
105 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
106 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
107 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
108 
109 import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
110 
111 import android.Manifest;
112 import android.annotation.IntDef;
113 import android.annotation.NonNull;
114 import android.annotation.Nullable;
115 import android.app.ActivityManager;
116 import android.app.AppOpsManager;
117 import android.app.BroadcastOptions;
118 import android.app.IActivityManager;
119 import android.app.ResourcesManager;
120 import android.app.admin.IDevicePolicyManager;
121 import android.app.admin.SecurityLog;
122 import android.app.backup.IBackupManager;
123 import android.content.BroadcastReceiver;
124 import android.content.ComponentName;
125 import android.content.ContentResolver;
126 import android.content.Context;
127 import android.content.IIntentReceiver;
128 import android.content.Intent;
129 import android.content.IntentFilter;
130 import android.content.IntentSender;
131 import android.content.IntentSender.SendIntentException;
132 import android.content.ServiceConnection;
133 import android.content.pm.ActivityInfo;
134 import android.content.pm.ApplicationInfo;
135 import android.content.pm.AppsQueryHelper;
136 import android.content.pm.AuxiliaryResolveInfo;
137 import android.content.pm.ChangedPackages;
138 import android.content.pm.ComponentInfo;
139 import android.content.pm.FallbackCategoryProvider;
140 import android.content.pm.FeatureInfo;
141 import android.content.pm.IDexModuleRegisterCallback;
142 import android.content.pm.IOnPermissionsChangeListener;
143 import android.content.pm.IPackageDataObserver;
144 import android.content.pm.IPackageDeleteObserver;
145 import android.content.pm.IPackageDeleteObserver2;
146 import android.content.pm.IPackageInstallObserver2;
147 import android.content.pm.IPackageInstaller;
148 import android.content.pm.IPackageManager;
149 import android.content.pm.IPackageManagerNative;
150 import android.content.pm.IPackageMoveObserver;
151 import android.content.pm.IPackageStatsObserver;
152 import android.content.pm.InstantAppInfo;
153 import android.content.pm.InstantAppRequest;
154 import android.content.pm.InstantAppResolveInfo;
155 import android.content.pm.InstrumentationInfo;
156 import android.content.pm.IntentFilterVerificationInfo;
157 import android.content.pm.KeySet;
158 import android.content.pm.PackageCleanItem;
159 import android.content.pm.PackageInfo;
160 import android.content.pm.PackageInfoLite;
161 import android.content.pm.PackageInstaller;
162 import android.content.pm.PackageManager;
163 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
164 import android.content.pm.PackageManagerInternal;
165 import android.content.pm.PackageParser;
166 import android.content.pm.PackageParser.ActivityIntentInfo;
167 import android.content.pm.PackageParser.PackageLite;
168 import android.content.pm.PackageParser.PackageParserException;
169 import android.content.pm.PackageStats;
170 import android.content.pm.PackageUserState;
171 import android.content.pm.ParceledListSlice;
172 import android.content.pm.PermissionGroupInfo;
173 import android.content.pm.PermissionInfo;
174 import android.content.pm.ProviderInfo;
175 import android.content.pm.ResolveInfo;
176 import android.content.pm.ServiceInfo;
177 import android.content.pm.SharedLibraryInfo;
178 import android.content.pm.Signature;
179 import android.content.pm.UserInfo;
180 import android.content.pm.VerifierDeviceIdentity;
181 import android.content.pm.VerifierInfo;
182 import android.content.pm.VersionedPackage;
183 import android.content.res.Resources;
184 import android.database.ContentObserver;
185 import android.graphics.Bitmap;
186 import android.hardware.display.DisplayManager;
187 import android.net.Uri;
188 import android.os.AsyncTask;
189 import android.os.Binder;
190 import android.os.Build;
191 import android.os.Bundle;
192 import android.os.Debug;
193 import android.os.Environment;
194 import android.os.Environment.UserEnvironment;
195 import android.os.FileUtils;
196 import android.os.Handler;
197 import android.os.IBinder;
198 import android.os.Looper;
199 import android.os.Message;
200 import android.os.Parcel;
201 import android.os.ParcelFileDescriptor;
202 import android.os.PatternMatcher;
203 import android.os.Process;
204 import android.os.RemoteCallbackList;
205 import android.os.RemoteException;
206 import android.os.ResultReceiver;
207 import android.os.SELinux;
208 import android.os.ServiceManager;
209 import android.os.ShellCallback;
210 import android.os.SystemClock;
211 import android.os.SystemProperties;
212 import android.os.Trace;
213 import android.os.UserHandle;
214 import android.os.UserManager;
215 import android.os.UserManagerInternal;
216 import android.os.storage.IStorageManager;
217 import android.os.storage.StorageEventListener;
218 import android.os.storage.StorageManager;
219 import android.os.storage.StorageManagerInternal;
220 import android.os.storage.VolumeInfo;
221 import android.os.storage.VolumeRecord;
222 import android.provider.Settings.Global;
223 import android.provider.Settings.Secure;
224 import android.security.KeyStore;
225 import android.security.SystemKeyStore;
226 import android.service.pm.PackageServiceDumpProto;
227 import android.system.ErrnoException;
228 import android.system.Os;
229 import android.text.TextUtils;
230 import android.text.format.DateUtils;
231 import android.util.ArrayMap;
232 import android.util.ArraySet;
233 import android.util.Base64;
234 import android.util.TimingsTraceLog;
235 import android.util.DisplayMetrics;
236 import android.util.EventLog;
237 import android.util.ExceptionUtils;
238 import android.util.Log;
239 import android.util.LogPrinter;
240 import android.util.MathUtils;
241 import android.util.PackageUtils;
242 import android.util.Pair;
243 import android.util.PrintStreamPrinter;
244 import android.util.Slog;
245 import android.util.SparseArray;
246 import android.util.SparseBooleanArray;
247 import android.util.SparseIntArray;
248 import android.util.Xml;
249 import android.util.jar.StrictJarFile;
250 import android.util.proto.ProtoOutputStream;
251 import android.view.Display;
252 
253 import com.android.internal.R;
254 import com.android.internal.annotations.GuardedBy;
255 import com.android.internal.app.IMediaContainerService;
256 import com.android.internal.app.ResolverActivity;
257 import com.android.internal.content.NativeLibraryHelper;
258 import com.android.internal.content.PackageHelper;
259 import com.android.internal.logging.MetricsLogger;
260 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
261 import com.android.internal.os.IParcelFileDescriptorFactory;
262 import com.android.internal.os.RoSystemProperties;
263 import com.android.internal.os.SomeArgs;
264 import com.android.internal.os.Zygote;
265 import com.android.internal.telephony.CarrierAppUtils;
266 import com.android.internal.util.ArrayUtils;
267 import com.android.internal.util.ConcurrentUtils;
268 import com.android.internal.util.DumpUtils;
269 import com.android.internal.util.FastPrintWriter;
270 import com.android.internal.util.FastXmlSerializer;
271 import com.android.internal.util.IndentingPrintWriter;
272 import com.android.internal.util.Preconditions;
273 import com.android.internal.util.XmlUtils;
274 import com.android.server.AttributeCache;
275 import com.android.server.DeviceIdleController;
276 import com.android.server.EventLogTags;
277 import com.android.server.FgThread;
278 import com.android.server.IntentResolver;
279 import com.android.server.LocalServices;
280 import com.android.server.LockGuard;
281 import com.android.server.ServiceThread;
282 import com.android.server.SystemConfig;
283 import com.android.server.SystemServerInitThreadPool;
284 import com.android.server.Watchdog;
285 import com.android.server.net.NetworkPolicyManagerInternal;
286 import com.android.server.pm.Installer.InstallerException;
287 import com.android.server.pm.PermissionsState.PermissionState;
288 import com.android.server.pm.Settings.DatabaseVersion;
289 import com.android.server.pm.Settings.VersionInfo;
290 import com.android.server.pm.dex.DexManager;
291 import com.android.server.pm.dex.DexoptOptions;
292 import com.android.server.pm.dex.PackageDexUsage;
293 import com.android.server.storage.DeviceStorageMonitorInternal;
294 
295 import dalvik.system.CloseGuard;
296 import dalvik.system.DexFile;
297 import dalvik.system.VMRuntime;
298 
299 import libcore.io.IoUtils;
300 import libcore.io.Streams;
301 import libcore.util.EmptyArray;
302 
303 import org.xmlpull.v1.XmlPullParser;
304 import org.xmlpull.v1.XmlPullParserException;
305 import org.xmlpull.v1.XmlSerializer;
306 
307 import java.io.BufferedOutputStream;
308 import java.io.BufferedReader;
309 import java.io.ByteArrayInputStream;
310 import java.io.ByteArrayOutputStream;
311 import java.io.File;
312 import java.io.FileDescriptor;
313 import java.io.FileInputStream;
314 import java.io.FileOutputStream;
315 import java.io.FileReader;
316 import java.io.FilenameFilter;
317 import java.io.IOException;
318 import java.io.InputStream;
319 import java.io.OutputStream;
320 import java.io.PrintWriter;
321 import java.lang.annotation.Retention;
322 import java.lang.annotation.RetentionPolicy;
323 import java.nio.charset.StandardCharsets;
324 import java.security.DigestInputStream;
325 import java.security.MessageDigest;
326 import java.security.NoSuchAlgorithmException;
327 import java.security.PublicKey;
328 import java.security.SecureRandom;
329 import java.security.cert.Certificate;
330 import java.security.cert.CertificateEncodingException;
331 import java.security.cert.CertificateException;
332 import java.text.SimpleDateFormat;
333 import java.util.ArrayList;
334 import java.util.Arrays;
335 import java.util.Collection;
336 import java.util.Collections;
337 import java.util.Comparator;
338 import java.util.Date;
339 import java.util.HashMap;
340 import java.util.HashSet;
341 import java.util.Iterator;
342 import java.util.List;
343 import java.util.Map;
344 import java.util.Objects;
345 import java.util.Set;
346 import java.util.concurrent.CountDownLatch;
347 import java.util.concurrent.Future;
348 import java.util.concurrent.TimeUnit;
349 import java.util.concurrent.atomic.AtomicBoolean;
350 import java.util.concurrent.atomic.AtomicInteger;
351 import java.util.zip.GZIPInputStream;
352 
353 /**
354  * Keep track of all those APKs everywhere.
355  * <p>
356  * Internally there are two important locks:
357  * <ul>
358  * <li>{@link #mPackages} is used to guard all in-memory parsed package details
359  * and other related state. It is a fine-grained lock that should only be held
360  * momentarily, as it's one of the most contended locks in the system.
361  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
362  * operations typically involve heavy lifting of application data on disk. Since
363  * {@code installd} is single-threaded, and it's operations can often be slow,
364  * this lock should never be acquired while already holding {@link #mPackages}.
365  * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
366  * holding {@link #mInstallLock}.
367  * </ul>
368  * Many internal methods rely on the caller to hold the appropriate locks, and
369  * this contract is expressed through method name suffixes:
370  * <ul>
371  * <li>fooLI(): the caller must hold {@link #mInstallLock}
372  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
373  * being modified must be frozen
374  * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
375  * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
376  * </ul>
377  * <p>
378  * Because this class is very central to the platform's security; please run all
379  * CTS and unit tests whenever making modifications:
380  *
381  * <pre>
382  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
383  * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
384  * </pre>
385  */
386 public class PackageManagerService extends IPackageManager.Stub
387         implements PackageSender {
388     static final String TAG = "PackageManager";
389     static final boolean DEBUG_SETTINGS = false;
390     static final boolean DEBUG_PREFERRED = false;
391     static final boolean DEBUG_UPGRADE = false;
392     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
393     private static final boolean DEBUG_BACKUP = false;
394     private static final boolean DEBUG_INSTALL = false;
395     private static final boolean DEBUG_REMOVE = false;
396     private static final boolean DEBUG_BROADCASTS = false;
397     private static final boolean DEBUG_SHOW_INFO = false;
398     private static final boolean DEBUG_PACKAGE_INFO = false;
399     private static final boolean DEBUG_INTENT_MATCHING = false;
400     private static final boolean DEBUG_PACKAGE_SCANNING = false;
401     private static final boolean DEBUG_VERIFY = false;
402     private static final boolean DEBUG_FILTERS = false;
403     private static final boolean DEBUG_PERMISSIONS = false;
404     private static final boolean DEBUG_SHARED_LIBRARIES = false;
405     private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
406 
407     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
408     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
409     // user, but by default initialize to this.
410     public static final boolean DEBUG_DEXOPT = false;
411 
412     private static final boolean DEBUG_ABI_SELECTION = false;
413     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
414     private static final boolean DEBUG_TRIAGED_MISSING = false;
415     private static final boolean DEBUG_APP_DATA = false;
416 
417     /** REMOVE. According to Svet, this was only used to reset permissions during development. */
418     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
419 
420     private static final boolean HIDE_EPHEMERAL_APIS = false;
421 
422     private static final boolean ENABLE_FREE_CACHE_V2 =
423             SystemProperties.getBoolean("fw.free_cache_v2", true);
424 
425     private static final int RADIO_UID = Process.PHONE_UID;
426     private static final int LOG_UID = Process.LOG_UID;
427     private static final int NFC_UID = Process.NFC_UID;
428     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
429     private static final int SHELL_UID = Process.SHELL_UID;
430 
431     // Cap the size of permission trees that 3rd party apps can define
432     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
433 
434     // Suffix used during package installation when copying/moving
435     // package apks to install directory.
436     private static final String INSTALL_PACKAGE_SUFFIX = "-";
437 
438     static final int SCAN_NO_DEX = 1<<1;
439     static final int SCAN_FORCE_DEX = 1<<2;
440     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
441     static final int SCAN_NEW_INSTALL = 1<<4;
442     static final int SCAN_UPDATE_TIME = 1<<5;
443     static final int SCAN_BOOTING = 1<<6;
444     static final int SCAN_TRUSTED_OVERLAY = 1<<7;
445     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
446     static final int SCAN_REPLACING = 1<<9;
447     static final int SCAN_REQUIRE_KNOWN = 1<<10;
448     static final int SCAN_MOVE = 1<<11;
449     static final int SCAN_INITIAL = 1<<12;
450     static final int SCAN_CHECK_ONLY = 1<<13;
451     static final int SCAN_DONT_KILL_APP = 1<<14;
452     static final int SCAN_IGNORE_FROZEN = 1<<15;
453     static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
454     static final int SCAN_AS_INSTANT_APP = 1<<17;
455     static final int SCAN_AS_FULL_APP = 1<<18;
456     static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<19;
457     /** Should not be with the scan flags */
458     static final int FLAGS_REMOVE_CHATTY = 1<<31;
459 
460     private static final String STATIC_SHARED_LIB_DELIMITER = "_";
461     /** Extension of the compressed packages */
462     private final static String COMPRESSED_EXTENSION = ".gz";
463     /** Suffix of stub packages on the system partition */
464     private final static String STUB_SUFFIX = "-Stub";
465 
466     private static final int[] EMPTY_INT_ARRAY = new int[0];
467 
468     private static final int TYPE_UNKNOWN = 0;
469     private static final int TYPE_ACTIVITY = 1;
470     private static final int TYPE_RECEIVER = 2;
471     private static final int TYPE_SERVICE = 3;
472     private static final int TYPE_PROVIDER = 4;
473     @IntDef(prefix = { "TYPE_" }, value = {
474             TYPE_UNKNOWN,
475             TYPE_ACTIVITY,
476             TYPE_RECEIVER,
477             TYPE_SERVICE,
478             TYPE_PROVIDER,
479     })
480     @Retention(RetentionPolicy.SOURCE)
481     public @interface ComponentType {}
482 
483     /**
484      * Timeout (in milliseconds) after which the watchdog should declare that
485      * our handler thread is wedged.  The usual default for such things is one
486      * minute but we sometimes do very lengthy I/O operations on this thread,
487      * such as installing multi-gigabyte applications, so ours needs to be longer.
488      */
489     static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
490 
491     /**
492      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
493      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
494      * settings entry if available, otherwise we use the hardcoded default.  If it's been
495      * more than this long since the last fstrim, we force one during the boot sequence.
496      *
497      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
498      * one gets run at the next available charging+idle time.  This final mandatory
499      * no-fstrim check kicks in only of the other scheduling criteria is never met.
500      */
501     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
502 
503     /**
504      * Whether verification is enabled by default.
505      */
506     private static final boolean DEFAULT_VERIFY_ENABLE = true;
507 
508     /**
509      * The default maximum time to wait for the verification agent to return in
510      * milliseconds.
511      */
512     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
513 
514     /**
515      * The default response for package verification timeout.
516      *
517      * This can be either PackageManager.VERIFICATION_ALLOW or
518      * PackageManager.VERIFICATION_REJECT.
519      */
520     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
521 
522     static final String PLATFORM_PACKAGE_NAME = "android";
523 
524     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
525 
526     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
527             DEFAULT_CONTAINER_PACKAGE,
528             "com.android.defcontainer.DefaultContainerService");
529 
530     private static final String KILL_APP_REASON_GIDS_CHANGED =
531             "permission grant or revoke changed gids";
532 
533     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
534             "permissions revoked";
535 
536     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
537 
538     private static final String PACKAGE_SCHEME = "package";
539 
540     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
541 
542     /** Permission grant: not grant the permission. */
543     private static final int GRANT_DENIED = 1;
544 
545     /** Permission grant: grant the permission as an install permission. */
546     private static final int GRANT_INSTALL = 2;
547 
548     /** Permission grant: grant the permission as a runtime one. */
549     private static final int GRANT_RUNTIME = 3;
550 
551     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
552     private static final int GRANT_UPGRADE = 4;
553 
554     /** Canonical intent used to identify what counts as a "web browser" app */
555     private static final Intent sBrowserIntent;
556     static {
557         sBrowserIntent = new Intent();
558         sBrowserIntent.setAction(Intent.ACTION_VIEW);
559         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
560         sBrowserIntent.setData(Uri.parse("http:"));
561     }
562 
563     /**
564      * The set of all protected actions [i.e. those actions for which a high priority
565      * intent filter is disallowed].
566      */
567     private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
568     static {
569         PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
570         PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
571         PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
572         PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
573     }
574 
575     // Compilation reasons.
576     public static final int REASON_FIRST_BOOT = 0;
577     public static final int REASON_BOOT = 1;
578     public static final int REASON_INSTALL = 2;
579     public static final int REASON_BACKGROUND_DEXOPT = 3;
580     public static final int REASON_AB_OTA = 4;
581     public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
582     public static final int REASON_SHARED = 6;
583 
584     public static final int REASON_LAST = REASON_SHARED;
585 
586     /** All dangerous permission names in the same order as the events in MetricsEvent */
587     private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
588             Manifest.permission.READ_CALENDAR,
589             Manifest.permission.WRITE_CALENDAR,
590             Manifest.permission.CAMERA,
591             Manifest.permission.READ_CONTACTS,
592             Manifest.permission.WRITE_CONTACTS,
593             Manifest.permission.GET_ACCOUNTS,
594             Manifest.permission.ACCESS_FINE_LOCATION,
595             Manifest.permission.ACCESS_COARSE_LOCATION,
596             Manifest.permission.RECORD_AUDIO,
597             Manifest.permission.READ_PHONE_STATE,
598             Manifest.permission.CALL_PHONE,
599             Manifest.permission.READ_CALL_LOG,
600             Manifest.permission.WRITE_CALL_LOG,
601             Manifest.permission.ADD_VOICEMAIL,
602             Manifest.permission.USE_SIP,
603             Manifest.permission.PROCESS_OUTGOING_CALLS,
604             Manifest.permission.READ_CELL_BROADCASTS,
605             Manifest.permission.BODY_SENSORS,
606             Manifest.permission.SEND_SMS,
607             Manifest.permission.RECEIVE_SMS,
608             Manifest.permission.READ_SMS,
609             Manifest.permission.RECEIVE_WAP_PUSH,
610             Manifest.permission.RECEIVE_MMS,
611             Manifest.permission.READ_EXTERNAL_STORAGE,
612             Manifest.permission.WRITE_EXTERNAL_STORAGE,
613             Manifest.permission.READ_PHONE_NUMBERS,
614             Manifest.permission.ANSWER_PHONE_CALLS);
615 
616 
617     /**
618      * Version number for the package parser cache. Increment this whenever the format or
619      * extent of cached data changes. See {@code PackageParser#setCacheDir}.
620      */
621     private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
622 
623     /**
624      * Whether the package parser cache is enabled.
625      */
626     private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
627 
628     final ServiceThread mHandlerThread;
629 
630     final PackageHandler mHandler;
631 
632     private final ProcessLoggingHandler mProcessLoggingHandler;
633 
634     /**
635      * Messages for {@link #mHandler} that need to wait for system ready before
636      * being dispatched.
637      */
638     private ArrayList<Message> mPostSystemReadyMessages;
639 
640     final int mSdkVersion = Build.VERSION.SDK_INT;
641 
642     final Context mContext;
643     final boolean mFactoryTest;
644     final boolean mOnlyCore;
645     final DisplayMetrics mMetrics;
646     final int mDefParseFlags;
647     final String[] mSeparateProcesses;
648     final boolean mIsUpgrade;
649     final boolean mIsPreNUpgrade;
650     final boolean mIsPreNMR1Upgrade;
651 
652     // Have we told the Activity Manager to whitelist the default container service by uid yet?
653     @GuardedBy("mPackages")
654     boolean mDefaultContainerWhitelisted = false;
655 
656     @GuardedBy("mPackages")
657     private boolean mDexOptDialogShown;
658 
659     /** The location for ASEC container files on internal storage. */
660     final String mAsecInternalPath;
661 
662     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
663     // LOCK HELD.  Can be called with mInstallLock held.
664     @GuardedBy("mInstallLock")
665     final Installer mInstaller;
666 
667     /** Directory where installed third-party apps stored */
668     final File mAppInstallDir;
669 
670     /**
671      * Directory to which applications installed internally have their
672      * 32 bit native libraries copied.
673      */
674     private File mAppLib32InstallDir;
675 
676     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
677     // apps.
678     final File mDrmAppPrivateInstallDir;
679 
680     // ----------------------------------------------------------------
681 
682     // Lock for state used when installing and doing other long running
683     // operations.  Methods that must be called with this lock held have
684     // the suffix "LI".
685     final Object mInstallLock = new Object();
686 
687     // ----------------------------------------------------------------
688 
689     // Keys are String (package name), values are Package.  This also serves
690     // as the lock for the global state.  Methods that must be called with
691     // this lock held have the prefix "LP".
692     @GuardedBy("mPackages")
693     final ArrayMap<String, PackageParser.Package> mPackages =
694             new ArrayMap<String, PackageParser.Package>();
695 
696     final ArrayMap<String, Set<String>> mKnownCodebase =
697             new ArrayMap<String, Set<String>>();
698 
699     // Keys are isolated uids and values are the uid of the application
700     // that created the isolated proccess.
701     @GuardedBy("mPackages")
702     final SparseIntArray mIsolatedOwners = new SparseIntArray();
703 
704     /**
705      * Tracks new system packages [received in an OTA] that we expect to
706      * find updated user-installed versions. Keys are package name, values
707      * are package location.
708      */
709     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
710     /**
711      * Tracks high priority intent filters for protected actions. During boot, certain
712      * filter actions are protected and should never be allowed to have a high priority
713      * intent filter for them. However, there is one, and only one exception -- the
714      * setup wizard. It must be able to define a high priority intent filter for these
715      * actions to ensure there are no escapes from the wizard. We need to delay processing
716      * of these during boot as we need to look at all of the system packages in order
717      * to know which component is the setup wizard.
718      */
719     private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
720     /**
721      * Whether or not processing protected filters should be deferred.
722      */
723     private boolean mDeferProtectedFilters = true;
724 
725     /**
726      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
727      */
728     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
729     /**
730      * Whether or not system app permissions should be promoted from install to runtime.
731      */
732     boolean mPromoteSystemApps;
733 
734     @GuardedBy("mPackages")
735     final Settings mSettings;
736 
737     /**
738      * Set of package names that are currently "frozen", which means active
739      * surgery is being done on the code/data for that package. The platform
740      * will refuse to launch frozen packages to avoid race conditions.
741      *
742      * @see PackageFreezer
743      */
744     @GuardedBy("mPackages")
745     final ArraySet<String> mFrozenPackages = new ArraySet<>();
746 
747     final ProtectedPackages mProtectedPackages;
748 
749     @GuardedBy("mLoadedVolumes")
750     final ArraySet<String> mLoadedVolumes = new ArraySet<>();
751 
752     boolean mFirstBoot;
753 
754     PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
755 
756     // System configuration read by SystemConfig.
757     final int[] mGlobalGids;
758     final SparseArray<ArraySet<String>> mSystemPermissions;
759     @GuardedBy("mAvailableFeatures")
760     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
761 
762     // If mac_permissions.xml was found for seinfo labeling.
763     boolean mFoundPolicyFile;
764 
765     private final InstantAppRegistry mInstantAppRegistry;
766 
767     @GuardedBy("mPackages")
768     int mChangedPackagesSequenceNumber;
769     /**
770      * List of changed [installed, removed or updated] packages.
771      * mapping from user id -> sequence number -> package name
772      */
773     @GuardedBy("mPackages")
774     final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
775     /**
776      * The sequence number of the last change to a package.
777      * mapping from user id -> package name -> sequence number
778      */
779     @GuardedBy("mPackages")
780     final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
781 
782     class PackageParserCallback implements PackageParser.Callback {
hasFeature(String feature)783         @Override public final boolean hasFeature(String feature) {
784             return PackageManagerService.this.hasSystemFeature(feature, 0);
785         }
786 
getStaticOverlayPackagesLocked( Collection<PackageParser.Package> allPackages, String targetPackageName)787         final List<PackageParser.Package> getStaticOverlayPackagesLocked(
788                 Collection<PackageParser.Package> allPackages, String targetPackageName) {
789             List<PackageParser.Package> overlayPackages = null;
790             for (PackageParser.Package p : allPackages) {
791                 if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
792                     if (overlayPackages == null) {
793                         overlayPackages = new ArrayList<PackageParser.Package>();
794                     }
795                     overlayPackages.add(p);
796                 }
797             }
798             if (overlayPackages != null) {
799                 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
800                     public int compare(PackageParser.Package p1, PackageParser.Package p2) {
801                         return p1.mOverlayPriority - p2.mOverlayPriority;
802                     }
803                 };
804                 Collections.sort(overlayPackages, cmp);
805             }
806             return overlayPackages;
807         }
808 
getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages, String targetPackageName, String targetPath)809         final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
810                 String targetPackageName, String targetPath) {
811             if ("android".equals(targetPackageName)) {
812                 // Static RROs targeting to "android", ie framework-res.apk, are already applied by
813                 // native AssetManager.
814                 return null;
815             }
816             List<PackageParser.Package> overlayPackages =
817                     getStaticOverlayPackagesLocked(allPackages, targetPackageName);
818             if (overlayPackages == null || overlayPackages.isEmpty()) {
819                 return null;
820             }
821             List<String> overlayPathList = null;
822             for (PackageParser.Package overlayPackage : overlayPackages) {
823                 if (targetPath == null) {
824                     if (overlayPathList == null) {
825                         overlayPathList = new ArrayList<String>();
826                     }
827                     overlayPathList.add(overlayPackage.baseCodePath);
828                     continue;
829                 }
830 
831                 try {
832                     // Creates idmaps for system to parse correctly the Android manifest of the
833                     // target package.
834                     //
835                     // OverlayManagerService will update each of them with a correct gid from its
836                     // target package app id.
837                     mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
838                             UserHandle.getSharedAppGid(
839                                     UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
840                     if (overlayPathList == null) {
841                         overlayPathList = new ArrayList<String>();
842                     }
843                     overlayPathList.add(overlayPackage.baseCodePath);
844                 } catch (InstallerException e) {
845                     Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
846                             overlayPackage.baseCodePath);
847                 }
848             }
849             return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
850         }
851 
getStaticOverlayPaths(String targetPackageName, String targetPath)852         String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
853             synchronized (mPackages) {
854                 return getStaticOverlayPathsLocked(
855                         mPackages.values(), targetPackageName, targetPath);
856             }
857         }
858 
getOverlayApks(String targetPackageName)859         @Override public final String[] getOverlayApks(String targetPackageName) {
860             return getStaticOverlayPaths(targetPackageName, null);
861         }
862 
getOverlayPaths(String targetPackageName, String targetPath)863         @Override public final String[] getOverlayPaths(String targetPackageName,
864                 String targetPath) {
865             return getStaticOverlayPaths(targetPackageName, targetPath);
866         }
867     };
868 
869     class ParallelPackageParserCallback extends PackageParserCallback {
870         List<PackageParser.Package> mOverlayPackages = null;
871 
findStaticOverlayPackages()872         void findStaticOverlayPackages() {
873             synchronized (mPackages) {
874                 for (PackageParser.Package p : mPackages.values()) {
875                     if (p.mIsStaticOverlay) {
876                         if (mOverlayPackages == null) {
877                             mOverlayPackages = new ArrayList<PackageParser.Package>();
878                         }
879                         mOverlayPackages.add(p);
880                     }
881                 }
882             }
883         }
884 
885         @Override
getStaticOverlayPaths(String targetPackageName, String targetPath)886         synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
887             // We can trust mOverlayPackages without holding mPackages because package uninstall
888             // can't happen while running parallel parsing.
889             // Moreover holding mPackages on each parsing thread causes dead-lock.
890             return mOverlayPackages == null ? null :
891                     getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
892         }
893     }
894 
895     final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
896     final ParallelPackageParserCallback mParallelPackageParserCallback =
897             new ParallelPackageParserCallback();
898 
899     public static final class SharedLibraryEntry {
900         public final @Nullable String path;
901         public final @Nullable String apk;
902         public final @NonNull SharedLibraryInfo info;
903 
SharedLibraryEntry(String _path, String _apk, String name, int version, int type, String declaringPackageName, int declaringPackageVersionCode)904         SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
905                 String declaringPackageName, int declaringPackageVersionCode) {
906             path = _path;
907             apk = _apk;
908             info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
909                     declaringPackageName, declaringPackageVersionCode), null);
910         }
911     }
912 
913     // Currently known shared libraries.
914     final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
915     final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
916             new ArrayMap<>();
917 
918     // All available activities, for your resolving pleasure.
919     final ActivityIntentResolver mActivities =
920             new ActivityIntentResolver();
921 
922     // All available receivers, for your resolving pleasure.
923     final ActivityIntentResolver mReceivers =
924             new ActivityIntentResolver();
925 
926     // All available services, for your resolving pleasure.
927     final ServiceIntentResolver mServices = new ServiceIntentResolver();
928 
929     // All available providers, for your resolving pleasure.
930     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
931 
932     // Mapping from provider base names (first directory in content URI codePath)
933     // to the provider information.
934     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
935             new ArrayMap<String, PackageParser.Provider>();
936 
937     // Mapping from instrumentation class names to info about them.
938     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
939             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
940 
941     // Mapping from permission names to info about them.
942     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
943             new ArrayMap<String, PackageParser.PermissionGroup>();
944 
945     // Packages whose data we have transfered into another package, thus
946     // should no longer exist.
947     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
948 
949     // Broadcast actions that are only available to the system.
950     @GuardedBy("mProtectedBroadcasts")
951     final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
952 
953     /** List of packages waiting for verification. */
954     final SparseArray<PackageVerificationState> mPendingVerification
955             = new SparseArray<PackageVerificationState>();
956 
957     /** Set of packages associated with each app op permission. */
958     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
959 
960     final PackageInstallerService mInstallerService;
961 
962     private final PackageDexOptimizer mPackageDexOptimizer;
963     // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
964     // is used by other apps).
965     private final DexManager mDexManager;
966 
967     private AtomicInteger mNextMoveId = new AtomicInteger();
968     private final MoveCallbacks mMoveCallbacks;
969 
970     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
971 
972     // Cache of users who need badging.
973     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
974 
975     /** Token for keys in mPendingVerification. */
976     private int mPendingVerificationToken = 0;
977 
978     volatile boolean mSystemReady;
979     volatile boolean mSafeMode;
980     volatile boolean mHasSystemUidErrors;
981     private volatile boolean mEphemeralAppsDisabled;
982 
983     ApplicationInfo mAndroidApplication;
984     final ActivityInfo mResolveActivity = new ActivityInfo();
985     final ResolveInfo mResolveInfo = new ResolveInfo();
986     ComponentName mResolveComponentName;
987     PackageParser.Package mPlatformPackage;
988     ComponentName mCustomResolverComponentName;
989 
990     boolean mResolverReplaced = false;
991 
992     private final @Nullable ComponentName mIntentFilterVerifierComponent;
993     private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
994 
995     private int mIntentFilterVerificationToken = 0;
996 
997     /** The service connection to the ephemeral resolver */
998     final EphemeralResolverConnection mInstantAppResolverConnection;
999     /** Component used to show resolver settings for Instant Apps */
1000     final ComponentName mInstantAppResolverSettingsComponent;
1001 
1002     /** Activity used to install instant applications */
1003     ActivityInfo mInstantAppInstallerActivity;
1004     final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1005 
1006     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
1007             = new SparseArray<IntentFilterVerificationState>();
1008 
1009     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1010 
1011     // List of packages names to keep cached, even if they are uninstalled for all users
1012     private List<String> mKeepUninstalledPackages;
1013 
1014     private UserManagerInternal mUserManagerInternal;
1015 
1016     private DeviceIdleController.LocalService mDeviceIdleController;
1017 
1018     private File mCacheDir;
1019 
1020     private ArraySet<String> mPrivappPermissionsViolations;
1021 
1022     private Future<?> mPrepareAppDataFuture;
1023 
1024     private static class IFVerificationParams {
1025         PackageParser.Package pkg;
1026         boolean replacing;
1027         int userId;
1028         int verifierUid;
1029 
IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, int _userId, int _verifierUid)1030         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1031                 int _userId, int _verifierUid) {
1032             pkg = _pkg;
1033             replacing = _replacing;
1034             userId = _userId;
1035             replacing = _replacing;
1036             verifierUid = _verifierUid;
1037         }
1038     }
1039 
1040     private interface IntentFilterVerifier<T extends IntentFilter> {
addOneIntentFilterVerification(int verifierId, int userId, int verificationId, T filter, String packageName)1041         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1042                                                T filter, String packageName);
startVerifications(int userId)1043         void startVerifications(int userId);
receiveVerificationResponse(int verificationId)1044         void receiveVerificationResponse(int verificationId);
1045     }
1046 
1047     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1048         private Context mContext;
1049         private ComponentName mIntentFilterVerifierComponent;
1050         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1051 
IntentVerifierProxy(Context context, ComponentName verifierComponent)1052         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1053             mContext = context;
1054             mIntentFilterVerifierComponent = verifierComponent;
1055         }
1056 
getDefaultScheme()1057         private String getDefaultScheme() {
1058             return IntentFilter.SCHEME_HTTPS;
1059         }
1060 
1061         @Override
startVerifications(int userId)1062         public void startVerifications(int userId) {
1063             // Launch verifications requests
1064             int count = mCurrentIntentFilterVerifications.size();
1065             for (int n=0; n<count; n++) {
1066                 int verificationId = mCurrentIntentFilterVerifications.get(n);
1067                 final IntentFilterVerificationState ivs =
1068                         mIntentFilterVerificationStates.get(verificationId);
1069 
1070                 String packageName = ivs.getPackageName();
1071 
1072                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1073                 final int filterCount = filters.size();
1074                 ArraySet<String> domainsSet = new ArraySet<>();
1075                 for (int m=0; m<filterCount; m++) {
1076                     PackageParser.ActivityIntentInfo filter = filters.get(m);
1077                     domainsSet.addAll(filter.getHostsList());
1078                 }
1079                 synchronized (mPackages) {
1080                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
1081                             packageName, domainsSet) != null) {
1082                         scheduleWriteSettingsLocked();
1083                     }
1084                 }
1085                 sendVerificationRequest(verificationId, ivs);
1086             }
1087             mCurrentIntentFilterVerifications.clear();
1088         }
1089 
sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs)1090         private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1091             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1092             verificationIntent.putExtra(
1093                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1094                     verificationId);
1095             verificationIntent.putExtra(
1096                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1097                     getDefaultScheme());
1098             verificationIntent.putExtra(
1099                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1100                     ivs.getHostsString());
1101             verificationIntent.putExtra(
1102                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1103                     ivs.getPackageName());
1104             verificationIntent.setComponent(mIntentFilterVerifierComponent);
1105             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1106 
1107             final long whitelistTimeout = getVerificationTimeout();
1108             final BroadcastOptions options = BroadcastOptions.makeBasic();
1109             options.setTemporaryAppWhitelistDuration(whitelistTimeout);
1110 
1111             DeviceIdleController.LocalService idleController = getDeviceIdleController();
1112             idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1113                     mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout,
1114                     UserHandle.USER_SYSTEM, true, "intent filter verifier");
1115 
1116             mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1117             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1118                     "Sending IntentFilter verification broadcast");
1119         }
1120 
receiveVerificationResponse(int verificationId)1121         public void receiveVerificationResponse(int verificationId) {
1122             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1123 
1124             final boolean verified = ivs.isVerified();
1125 
1126             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1127             final int count = filters.size();
1128             if (DEBUG_DOMAIN_VERIFICATION) {
1129                 Slog.i(TAG, "Received verification response " + verificationId
1130                         + " for " + count + " filters, verified=" + verified);
1131             }
1132             for (int n=0; n<count; n++) {
1133                 PackageParser.ActivityIntentInfo filter = filters.get(n);
1134                 filter.setVerified(verified);
1135 
1136                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1137                         + " verified with result:" + verified + " and hosts:"
1138                         + ivs.getHostsString());
1139             }
1140 
1141             mIntentFilterVerificationStates.remove(verificationId);
1142 
1143             final String packageName = ivs.getPackageName();
1144             IntentFilterVerificationInfo ivi = null;
1145 
1146             synchronized (mPackages) {
1147                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1148             }
1149             if (ivi == null) {
1150                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1151                         + verificationId + " packageName:" + packageName);
1152                 return;
1153             }
1154 
1155             synchronized (mPackages) {
1156                 if (verified) {
1157                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1158                 } else {
1159                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1160                 }
1161                 scheduleWriteSettingsLocked();
1162 
1163                 final int userId = ivs.getUserId();
1164                 if (userId != UserHandle.USER_ALL) {
1165                     final int userStatus =
1166                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1167 
1168                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1169                     boolean needUpdate = false;
1170 
1171                     // In a success case, we promote from undefined or ASK to ALWAYS.  This
1172                     // supports a flow where the app fails validation but then ships an updated
1173                     // APK that passes, and therefore deserves to be in ALWAYS.
1174                     //
1175                     // If validation failed, the undefined state winds up in the basic ASK behavior,
1176                     // but apps that previously passed and became ALWAYS are *demoted* out of
1177                     // that state, since they would not deserve the ALWAYS behavior in case of a
1178                     // clean install.
1179                      switch (userStatus) {
1180                          case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
1181                              if (!verified) {
1182                                  // Don't demote if sysconfig says 'always'
1183                                  SystemConfig systemConfig = SystemConfig.getInstance();
1184                                  ArraySet<String> packages = systemConfig.getLinkedApps();
1185                                  if (!packages.contains(packageName)) {
1186                                      // updatedStatus is already UNDEFINED
1187                                      needUpdate = true;
1188 
1189                                      if (DEBUG_DOMAIN_VERIFICATION) {
1190                                          Slog.d(TAG, "Formerly validated but now failing; demoting");
1191                                      }
1192                                  } else {
1193                                      if (DEBUG_DOMAIN_VERIFICATION) {
1194                                          Slog.d(TAG, "Updating bundled package " + packageName
1195                                                  + " failed autoVerify, but sysconfig supersedes");
1196                                      }
1197                                      // leave needUpdate == false here intentionally
1198                                  }
1199                              }
1200                              break;
1201 
1202                          case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1203                              // Stay in 'undefined' on verification failure
1204                              if (verified) {
1205                                  updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1206                              }
1207                              needUpdate = true;
1208                              if (DEBUG_DOMAIN_VERIFICATION) {
1209                                  Slog.d(TAG, "Applying update; old=" + userStatus
1210                                          + " new=" + updatedStatus);
1211                              }
1212                              break;
1213 
1214                          case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1215                              // Keep in 'ask' on failure
1216                              if (verified) {
1217                                  updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1218                                  needUpdate = true;
1219                              }
1220                              break;
1221 
1222                          default:
1223                              // Nothing to do
1224                       }
1225 
1226                     if (needUpdate) {
1227                         mSettings.updateIntentFilterVerificationStatusLPw(
1228                                 packageName, updatedStatus, userId);
1229                         scheduleWritePackageRestrictionsLocked(userId);
1230                     }
1231                 } else {
1232                     Slog.i(TAG, "autoVerify ignored when installing for all users");
1233                 }
1234              }
1235         }
1236 
1237         @Override
addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, ActivityIntentInfo filter, String packageName)1238         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1239                     ActivityIntentInfo filter, String packageName) {
1240             if (!hasValidDomains(filter)) {
1241                 return false;
1242             }
1243             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1244             if (ivs == null) {
1245                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1246                         packageName);
1247             }
1248             if (DEBUG_DOMAIN_VERIFICATION) {
1249                 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1250             }
1251             ivs.addFilter(filter);
1252             return true;
1253         }
1254 
createDomainVerificationState(int verifierUid, int userId, int verificationId, String packageName)1255         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1256                 int userId, int verificationId, String packageName) {
1257             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1258                     verifierUid, userId, packageName);
1259             ivs.setPendingState();
1260             synchronized (mPackages) {
1261                 mIntentFilterVerificationStates.append(verificationId, ivs);
1262                 mCurrentIntentFilterVerifications.add(verificationId);
1263             }
1264             return ivs;
1265         }
1266     }
1267 
hasValidDomains(ActivityIntentInfo filter)1268     private static boolean hasValidDomains(ActivityIntentInfo filter) {
1269         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1270                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1271                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1272     }
1273 
1274     // Set of pending broadcasts for aggregating enable/disable of components.
1275     static class PendingPackageBroadcasts {
1276         // for each user id, a map of <package name -> components within that package>
1277         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1278 
PendingPackageBroadcasts()1279         public PendingPackageBroadcasts() {
1280             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1281         }
1282 
get(int userId, String packageName)1283         public ArrayList<String> get(int userId, String packageName) {
1284             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1285             return packages.get(packageName);
1286         }
1287 
put(int userId, String packageName, ArrayList<String> components)1288         public void put(int userId, String packageName, ArrayList<String> components) {
1289             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1290             packages.put(packageName, components);
1291         }
1292 
remove(int userId, String packageName)1293         public void remove(int userId, String packageName) {
1294             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1295             if (packages != null) {
1296                 packages.remove(packageName);
1297             }
1298         }
1299 
remove(int userId)1300         public void remove(int userId) {
1301             mUidMap.remove(userId);
1302         }
1303 
userIdCount()1304         public int userIdCount() {
1305             return mUidMap.size();
1306         }
1307 
userIdAt(int n)1308         public int userIdAt(int n) {
1309             return mUidMap.keyAt(n);
1310         }
1311 
packagesForUserId(int userId)1312         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1313             return mUidMap.get(userId);
1314         }
1315 
size()1316         public int size() {
1317             // total number of pending broadcast entries across all userIds
1318             int num = 0;
1319             for (int i = 0; i< mUidMap.size(); i++) {
1320                 num += mUidMap.valueAt(i).size();
1321             }
1322             return num;
1323         }
1324 
clear()1325         public void clear() {
1326             mUidMap.clear();
1327         }
1328 
getOrAllocate(int userId)1329         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1330             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1331             if (map == null) {
1332                 map = new ArrayMap<String, ArrayList<String>>();
1333                 mUidMap.put(userId, map);
1334             }
1335             return map;
1336         }
1337     }
1338     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1339 
1340     // Service Connection to remote media container service to copy
1341     // package uri's from external media onto secure containers
1342     // or internal storage.
1343     private IMediaContainerService mContainerService = null;
1344 
1345     static final int SEND_PENDING_BROADCAST = 1;
1346     static final int MCS_BOUND = 3;
1347     static final int END_COPY = 4;
1348     static final int INIT_COPY = 5;
1349     static final int MCS_UNBIND = 6;
1350     static final int START_CLEANING_PACKAGE = 7;
1351     static final int FIND_INSTALL_LOC = 8;
1352     static final int POST_INSTALL = 9;
1353     static final int MCS_RECONNECT = 10;
1354     static final int MCS_GIVE_UP = 11;
1355     static final int UPDATED_MEDIA_STATUS = 12;
1356     static final int WRITE_SETTINGS = 13;
1357     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1358     static final int PACKAGE_VERIFIED = 15;
1359     static final int CHECK_PENDING_VERIFICATION = 16;
1360     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1361     static final int INTENT_FILTER_VERIFIED = 18;
1362     static final int WRITE_PACKAGE_LIST = 19;
1363     static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1364 
1365     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1366 
1367     // Delay time in millisecs
1368     static final int BROADCAST_DELAY = 10 * 1000;
1369 
1370     private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1371             2 * 60 * 60 * 1000L; /* two hours */
1372 
1373     static UserManagerService sUserManager;
1374 
1375     // Stores a list of users whose package restrictions file needs to be updated
1376     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1377 
1378     final private DefaultContainerConnection mDefContainerConn =
1379             new DefaultContainerConnection();
1380     class DefaultContainerConnection implements ServiceConnection {
onServiceConnected(ComponentName name, IBinder service)1381         public void onServiceConnected(ComponentName name, IBinder service) {
1382             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1383             final IMediaContainerService imcs = IMediaContainerService.Stub
1384                     .asInterface(Binder.allowBlocking(service));
1385             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1386         }
1387 
onServiceDisconnected(ComponentName name)1388         public void onServiceDisconnected(ComponentName name) {
1389             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1390         }
1391     }
1392 
1393     // Recordkeeping of restore-after-install operations that are currently in flight
1394     // between the Package Manager and the Backup Manager
1395     static class PostInstallData {
1396         public InstallArgs args;
1397         public PackageInstalledInfo res;
1398 
PostInstallData(InstallArgs _a, PackageInstalledInfo _r)1399         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1400             args = _a;
1401             res = _r;
1402         }
1403     }
1404 
1405     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1406     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1407 
1408     // XML tags for backup/restore of various bits of state
1409     private static final String TAG_PREFERRED_BACKUP = "pa";
1410     private static final String TAG_DEFAULT_APPS = "da";
1411     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1412 
1413     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1414     private static final String TAG_ALL_GRANTS = "rt-grants";
1415     private static final String TAG_GRANT = "grant";
1416     private static final String ATTR_PACKAGE_NAME = "pkg";
1417 
1418     private static final String TAG_PERMISSION = "perm";
1419     private static final String ATTR_PERMISSION_NAME = "name";
1420     private static final String ATTR_IS_GRANTED = "g";
1421     private static final String ATTR_USER_SET = "set";
1422     private static final String ATTR_USER_FIXED = "fixed";
1423     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1424 
1425     // System/policy permission grants are not backed up
1426     private static final int SYSTEM_RUNTIME_GRANT_MASK =
1427             FLAG_PERMISSION_POLICY_FIXED
1428             | FLAG_PERMISSION_SYSTEM_FIXED
1429             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1430 
1431     // And we back up these user-adjusted states
1432     private static final int USER_RUNTIME_GRANT_MASK =
1433             FLAG_PERMISSION_USER_SET
1434             | FLAG_PERMISSION_USER_FIXED
1435             | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1436 
1437     final @Nullable String mRequiredVerifierPackage;
1438     final @NonNull String mRequiredInstallerPackage;
1439     final @NonNull String mRequiredUninstallerPackage;
1440     final @Nullable String mSetupWizardPackage;
1441     final @Nullable String mStorageManagerPackage;
1442     final @NonNull String mServicesSystemSharedLibraryPackageName;
1443     final @NonNull String mSharedSystemSharedLibraryPackageName;
1444 
1445     final boolean mPermissionReviewRequired;
1446 
1447     private final PackageUsage mPackageUsage = new PackageUsage();
1448     private final CompilerStats mCompilerStats = new CompilerStats();
1449 
1450     class PackageHandler extends Handler {
1451         private boolean mBound = false;
1452         final ArrayList<HandlerParams> mPendingInstalls =
1453             new ArrayList<HandlerParams>();
1454 
connectToService()1455         private boolean connectToService() {
1456             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1457                     " DefaultContainerService");
1458             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1459             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1460             if (mContext.bindServiceAsUser(service, mDefContainerConn,
1461                     Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1462                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1463                 mBound = true;
1464                 return true;
1465             }
1466             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1467             return false;
1468         }
1469 
disconnectService()1470         private void disconnectService() {
1471             mContainerService = null;
1472             mBound = false;
1473             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1474             mContext.unbindService(mDefContainerConn);
1475             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1476         }
1477 
PackageHandler(Looper looper)1478         PackageHandler(Looper looper) {
1479             super(looper);
1480         }
1481 
handleMessage(Message msg)1482         public void handleMessage(Message msg) {
1483             try {
1484                 doHandleMessage(msg);
1485             } finally {
1486                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1487             }
1488         }
1489 
doHandleMessage(Message msg)1490         void doHandleMessage(Message msg) {
1491             switch (msg.what) {
1492                 case INIT_COPY: {
1493                     HandlerParams params = (HandlerParams) msg.obj;
1494                     int idx = mPendingInstalls.size();
1495                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1496                     // If a bind was already initiated we dont really
1497                     // need to do anything. The pending install
1498                     // will be processed later on.
1499                     if (!mBound) {
1500                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1501                                 System.identityHashCode(mHandler));
1502                         // If this is the only one pending we might
1503                         // have to bind to the service again.
1504                         if (!connectToService()) {
1505                             Slog.e(TAG, "Failed to bind to media container service");
1506                             params.serviceError();
1507                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1508                                     System.identityHashCode(mHandler));
1509                             if (params.traceMethod != null) {
1510                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1511                                         params.traceCookie);
1512                             }
1513                             return;
1514                         } else {
1515                             // Once we bind to the service, the first
1516                             // pending request will be processed.
1517                             mPendingInstalls.add(idx, params);
1518                         }
1519                     } else {
1520                         mPendingInstalls.add(idx, params);
1521                         // Already bound to the service. Just make
1522                         // sure we trigger off processing the first request.
1523                         if (idx == 0) {
1524                             mHandler.sendEmptyMessage(MCS_BOUND);
1525                         }
1526                     }
1527                     break;
1528                 }
1529                 case MCS_BOUND: {
1530                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1531                     if (msg.obj != null) {
1532                         mContainerService = (IMediaContainerService) msg.obj;
1533                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1534                                 System.identityHashCode(mHandler));
1535                     }
1536                     if (mContainerService == null) {
1537                         if (!mBound) {
1538                             // Something seriously wrong since we are not bound and we are not
1539                             // waiting for connection. Bail out.
1540                             Slog.e(TAG, "Cannot bind to media container service");
1541                             for (HandlerParams params : mPendingInstalls) {
1542                                 // Indicate service bind error
1543                                 params.serviceError();
1544                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1545                                         System.identityHashCode(params));
1546                                 if (params.traceMethod != null) {
1547                                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1548                                             params.traceMethod, params.traceCookie);
1549                                 }
1550                                 return;
1551                             }
1552                             mPendingInstalls.clear();
1553                         } else {
1554                             Slog.w(TAG, "Waiting to connect to media container service");
1555                         }
1556                     } else if (mPendingInstalls.size() > 0) {
1557                         HandlerParams params = mPendingInstalls.get(0);
1558                         if (params != null) {
1559                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1560                                     System.identityHashCode(params));
1561                             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1562                             if (params.startCopy()) {
1563                                 // We are done...  look for more work or to
1564                                 // go idle.
1565                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
1566                                         "Checking for more work or unbind...");
1567                                 // Delete pending install
1568                                 if (mPendingInstalls.size() > 0) {
1569                                     mPendingInstalls.remove(0);
1570                                 }
1571                                 if (mPendingInstalls.size() == 0) {
1572                                     if (mBound) {
1573                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
1574                                                 "Posting delayed MCS_UNBIND");
1575                                         removeMessages(MCS_UNBIND);
1576                                         Message ubmsg = obtainMessage(MCS_UNBIND);
1577                                         // Unbind after a little delay, to avoid
1578                                         // continual thrashing.
1579                                         sendMessageDelayed(ubmsg, 10000);
1580                                     }
1581                                 } else {
1582                                     // There are more pending requests in queue.
1583                                     // Just post MCS_BOUND message to trigger processing
1584                                     // of next pending install.
1585                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
1586                                             "Posting MCS_BOUND for next work");
1587                                     mHandler.sendEmptyMessage(MCS_BOUND);
1588                                 }
1589                             }
1590                             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1591                         }
1592                     } else {
1593                         // Should never happen ideally.
1594                         Slog.w(TAG, "Empty queue");
1595                     }
1596                     break;
1597                 }
1598                 case MCS_RECONNECT: {
1599                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1600                     if (mPendingInstalls.size() > 0) {
1601                         if (mBound) {
1602                             disconnectService();
1603                         }
1604                         if (!connectToService()) {
1605                             Slog.e(TAG, "Failed to bind to media container service");
1606                             for (HandlerParams params : mPendingInstalls) {
1607                                 // Indicate service bind error
1608                                 params.serviceError();
1609                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1610                                         System.identityHashCode(params));
1611                             }
1612                             mPendingInstalls.clear();
1613                         }
1614                     }
1615                     break;
1616                 }
1617                 case MCS_UNBIND: {
1618                     // If there is no actual work left, then time to unbind.
1619                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1620 
1621                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1622                         if (mBound) {
1623                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1624 
1625                             disconnectService();
1626                         }
1627                     } else if (mPendingInstalls.size() > 0) {
1628                         // There are more pending requests in queue.
1629                         // Just post MCS_BOUND message to trigger processing
1630                         // of next pending install.
1631                         mHandler.sendEmptyMessage(MCS_BOUND);
1632                     }
1633 
1634                     break;
1635                 }
1636                 case MCS_GIVE_UP: {
1637                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1638                     HandlerParams params = mPendingInstalls.remove(0);
1639                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1640                             System.identityHashCode(params));
1641                     break;
1642                 }
1643                 case SEND_PENDING_BROADCAST: {
1644                     String packages[];
1645                     ArrayList<String> components[];
1646                     int size = 0;
1647                     int uids[];
1648                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1649                     synchronized (mPackages) {
1650                         if (mPendingBroadcasts == null) {
1651                             return;
1652                         }
1653                         size = mPendingBroadcasts.size();
1654                         if (size <= 0) {
1655                             // Nothing to be done. Just return
1656                             return;
1657                         }
1658                         packages = new String[size];
1659                         components = new ArrayList[size];
1660                         uids = new int[size];
1661                         int i = 0;  // filling out the above arrays
1662 
1663                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1664                             int packageUserId = mPendingBroadcasts.userIdAt(n);
1665                             Iterator<Map.Entry<String, ArrayList<String>>> it
1666                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
1667                                             .entrySet().iterator();
1668                             while (it.hasNext() && i < size) {
1669                                 Map.Entry<String, ArrayList<String>> ent = it.next();
1670                                 packages[i] = ent.getKey();
1671                                 components[i] = ent.getValue();
1672                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1673                                 uids[i] = (ps != null)
1674                                         ? UserHandle.getUid(packageUserId, ps.appId)
1675                                         : -1;
1676                                 i++;
1677                             }
1678                         }
1679                         size = i;
1680                         mPendingBroadcasts.clear();
1681                     }
1682                     // Send broadcasts
1683                     for (int i = 0; i < size; i++) {
1684                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1685                     }
1686                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1687                     break;
1688                 }
1689                 case START_CLEANING_PACKAGE: {
1690                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1691                     final String packageName = (String)msg.obj;
1692                     final int userId = msg.arg1;
1693                     final boolean andCode = msg.arg2 != 0;
1694                     synchronized (mPackages) {
1695                         if (userId == UserHandle.USER_ALL) {
1696                             int[] users = sUserManager.getUserIds();
1697                             for (int user : users) {
1698                                 mSettings.addPackageToCleanLPw(
1699                                         new PackageCleanItem(user, packageName, andCode));
1700                             }
1701                         } else {
1702                             mSettings.addPackageToCleanLPw(
1703                                     new PackageCleanItem(userId, packageName, andCode));
1704                         }
1705                     }
1706                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1707                     startCleaningPackages();
1708                 } break;
1709                 case POST_INSTALL: {
1710                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1711 
1712                     PostInstallData data = mRunningInstalls.get(msg.arg1);
1713                     final boolean didRestore = (msg.arg2 != 0);
1714                     mRunningInstalls.delete(msg.arg1);
1715 
1716                     if (data != null) {
1717                         InstallArgs args = data.args;
1718                         PackageInstalledInfo parentRes = data.res;
1719 
1720                         final boolean grantPermissions = (args.installFlags
1721                                 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1722                         final boolean killApp = (args.installFlags
1723                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1724                         final boolean virtualPreload = ((args.installFlags
1725                                 & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1726                         final String[] grantedPermissions = args.installGrantPermissions;
1727 
1728                         // Handle the parent package
1729                         handlePackagePostInstall(parentRes, grantPermissions, killApp,
1730                                 virtualPreload, grantedPermissions, didRestore,
1731                                 args.installerPackageName, args.observer);
1732 
1733                         // Handle the child packages
1734                         final int childCount = (parentRes.addedChildPackages != null)
1735                                 ? parentRes.addedChildPackages.size() : 0;
1736                         for (int i = 0; i < childCount; i++) {
1737                             PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1738                             handlePackagePostInstall(childRes, grantPermissions, killApp,
1739                                     virtualPreload, grantedPermissions, false /*didRestore*/,
1740                                     args.installerPackageName, args.observer);
1741                         }
1742 
1743                         // Log tracing if needed
1744                         if (args.traceMethod != null) {
1745                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1746                                     args.traceCookie);
1747                         }
1748                     } else {
1749                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1750                     }
1751 
1752                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1753                 } break;
1754                 case UPDATED_MEDIA_STATUS: {
1755                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1756                     boolean reportStatus = msg.arg1 == 1;
1757                     boolean doGc = msg.arg2 == 1;
1758                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1759                     if (doGc) {
1760                         // Force a gc to clear up stale containers.
1761                         Runtime.getRuntime().gc();
1762                     }
1763                     if (msg.obj != null) {
1764                         @SuppressWarnings("unchecked")
1765                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1766                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1767                         // Unload containers
1768                         unloadAllContainers(args);
1769                     }
1770                     if (reportStatus) {
1771                         try {
1772                             if (DEBUG_SD_INSTALL) Log.i(TAG,
1773                                     "Invoking StorageManagerService call back");
1774                             PackageHelper.getStorageManager().finishMediaUpdate();
1775                         } catch (RemoteException e) {
1776                             Log.e(TAG, "StorageManagerService not running?");
1777                         }
1778                     }
1779                 } break;
1780                 case WRITE_SETTINGS: {
1781                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1782                     synchronized (mPackages) {
1783                         removeMessages(WRITE_SETTINGS);
1784                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1785                         mSettings.writeLPr();
1786                         mDirtyUsers.clear();
1787                     }
1788                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1789                 } break;
1790                 case WRITE_PACKAGE_RESTRICTIONS: {
1791                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1792                     synchronized (mPackages) {
1793                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1794                         for (int userId : mDirtyUsers) {
1795                             mSettings.writePackageRestrictionsLPr(userId);
1796                         }
1797                         mDirtyUsers.clear();
1798                     }
1799                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1800                 } break;
1801                 case WRITE_PACKAGE_LIST: {
1802                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1803                     synchronized (mPackages) {
1804                         removeMessages(WRITE_PACKAGE_LIST);
1805                         mSettings.writePackageListLPr(msg.arg1);
1806                     }
1807                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1808                 } break;
1809                 case CHECK_PENDING_VERIFICATION: {
1810                     final int verificationId = msg.arg1;
1811                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1812 
1813                     if ((state != null) && !state.timeoutExtended()) {
1814                         final InstallArgs args = state.getInstallArgs();
1815                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1816 
1817                         Slog.i(TAG, "Verification timed out for " + originUri);
1818                         mPendingVerification.remove(verificationId);
1819 
1820                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1821 
1822                         final UserHandle user = args.getUser();
1823                         if (getDefaultVerificationResponse(user)
1824                                 == PackageManager.VERIFICATION_ALLOW) {
1825                             Slog.i(TAG, "Continuing with installation of " + originUri);
1826                             state.setVerifierResponse(Binder.getCallingUid(),
1827                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1828                             broadcastPackageVerified(verificationId, originUri,
1829                                     PackageManager.VERIFICATION_ALLOW, user);
1830                             try {
1831                                 ret = args.copyApk(mContainerService, true);
1832                             } catch (RemoteException e) {
1833                                 Slog.e(TAG, "Could not contact the ContainerService");
1834                             }
1835                         } else {
1836                             broadcastPackageVerified(verificationId, originUri,
1837                                     PackageManager.VERIFICATION_REJECT, user);
1838                         }
1839 
1840                         Trace.asyncTraceEnd(
1841                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1842 
1843                         processPendingInstall(args, ret);
1844                         mHandler.sendEmptyMessage(MCS_UNBIND);
1845                     }
1846                     break;
1847                 }
1848                 case PACKAGE_VERIFIED: {
1849                     final int verificationId = msg.arg1;
1850 
1851                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1852                     if (state == null) {
1853                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1854                         break;
1855                     }
1856 
1857                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1858 
1859                     state.setVerifierResponse(response.callerUid, response.code);
1860 
1861                     if (state.isVerificationComplete()) {
1862                         mPendingVerification.remove(verificationId);
1863 
1864                         final InstallArgs args = state.getInstallArgs();
1865                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1866 
1867                         int ret;
1868                         if (state.isInstallAllowed()) {
1869                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1870                             broadcastPackageVerified(verificationId, originUri,
1871                                     response.code, state.getInstallArgs().getUser());
1872                             try {
1873                                 ret = args.copyApk(mContainerService, true);
1874                             } catch (RemoteException e) {
1875                                 Slog.e(TAG, "Could not contact the ContainerService");
1876                             }
1877                         } else {
1878                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1879                         }
1880 
1881                         Trace.asyncTraceEnd(
1882                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1883 
1884                         processPendingInstall(args, ret);
1885                         mHandler.sendEmptyMessage(MCS_UNBIND);
1886                     }
1887 
1888                     break;
1889                 }
1890                 case START_INTENT_FILTER_VERIFICATIONS: {
1891                     IFVerificationParams params = (IFVerificationParams) msg.obj;
1892                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1893                             params.replacing, params.pkg);
1894                     break;
1895                 }
1896                 case INTENT_FILTER_VERIFIED: {
1897                     final int verificationId = msg.arg1;
1898 
1899                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1900                             verificationId);
1901                     if (state == null) {
1902                         Slog.w(TAG, "Invalid IntentFilter verification token "
1903                                 + verificationId + " received");
1904                         break;
1905                     }
1906 
1907                     final int userId = state.getUserId();
1908 
1909                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1910                             "Processing IntentFilter verification with token:"
1911                             + verificationId + " and userId:" + userId);
1912 
1913                     final IntentFilterVerificationResponse response =
1914                             (IntentFilterVerificationResponse) msg.obj;
1915 
1916                     state.setVerifierResponse(response.callerUid, response.code);
1917 
1918                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1919                             "IntentFilter verification with token:" + verificationId
1920                             + " and userId:" + userId
1921                             + " is settings verifier response with response code:"
1922                             + response.code);
1923 
1924                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1925                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1926                                 + response.getFailedDomainsString());
1927                     }
1928 
1929                     if (state.isVerificationComplete()) {
1930                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1931                     } else {
1932                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1933                                 "IntentFilter verification with token:" + verificationId
1934                                 + " was not said to be complete");
1935                     }
1936 
1937                     break;
1938                 }
1939                 case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1940                     InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1941                             mInstantAppResolverConnection,
1942                             (InstantAppRequest) msg.obj,
1943                             mInstantAppInstallerActivity,
1944                             mHandler);
1945                 }
1946             }
1947         }
1948     }
1949 
handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, boolean killApp, boolean virtualPreload, String[] grantedPermissions, boolean launchedForRestore, String installerPackage, IPackageInstallObserver2 installObserver)1950     private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1951             boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1952             boolean launchedForRestore, String installerPackage,
1953             IPackageInstallObserver2 installObserver) {
1954         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1955             // Send the removed broadcasts
1956             if (res.removedInfo != null) {
1957                 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1958             }
1959 
1960             // Now that we successfully installed the package, grant runtime
1961             // permissions if requested before broadcasting the install. Also
1962             // for legacy apps in permission review mode we clear the permission
1963             // review flag which is used to emulate runtime permissions for
1964             // legacy apps.
1965             if (grantPermissions) {
1966                 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1967             }
1968 
1969             final boolean update = res.removedInfo != null
1970                     && res.removedInfo.removedPackage != null;
1971             final String installerPackageName =
1972                     res.installerPackageName != null
1973                             ? res.installerPackageName
1974                             : res.removedInfo != null
1975                                     ? res.removedInfo.installerPackageName
1976                                     : null;
1977 
1978             // If this is the first time we have child packages for a disabled privileged
1979             // app that had no children, we grant requested runtime permissions to the new
1980             // children if the parent on the system image had them already granted.
1981             if (res.pkg.parentPackage != null) {
1982                 synchronized (mPackages) {
1983                     grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1984                 }
1985             }
1986 
1987             synchronized (mPackages) {
1988                 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1989             }
1990 
1991             final String packageName = res.pkg.applicationInfo.packageName;
1992 
1993             // Determine the set of users who are adding this package for
1994             // the first time vs. those who are seeing an update.
1995             int[] firstUsers = EMPTY_INT_ARRAY;
1996             int[] updateUsers = EMPTY_INT_ARRAY;
1997             final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1998             final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1999             for (int newUser : res.newUsers) {
2000                 if (ps.getInstantApp(newUser)) {
2001                     continue;
2002                 }
2003                 if (allNewUsers) {
2004                     firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
2005                     continue;
2006                 }
2007                 boolean isNew = true;
2008                 for (int origUser : res.origUsers) {
2009                     if (origUser == newUser) {
2010                         isNew = false;
2011                         break;
2012                     }
2013                 }
2014                 if (isNew) {
2015                     firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
2016                 } else {
2017                     updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
2018                 }
2019             }
2020 
2021             // Send installed broadcasts if the package is not a static shared lib.
2022             if (res.pkg.staticSharedLibName == null) {
2023                 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2024 
2025                 // Send added for users that see the package for the first time
2026                 // sendPackageAddedForNewUsers also deals with system apps
2027                 int appId = UserHandle.getAppId(res.uid);
2028                 boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2029                 sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2030                         virtualPreload /*startReceiver*/, appId, firstUsers);
2031 
2032                 // Send added for users that don't see the package for the first time
2033                 Bundle extras = new Bundle(1);
2034                 extras.putInt(Intent.EXTRA_UID, res.uid);
2035                 if (update) {
2036                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
2037                 }
2038                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2039                         extras, 0 /*flags*/,
2040                         null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
2041                 if (installerPackageName != null) {
2042                     sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2043                             extras, 0 /*flags*/,
2044                             installerPackageName, null /*finishedReceiver*/, updateUsers);
2045                 }
2046 
2047                 // Send replaced for users that don't see the package for the first time
2048                 if (update) {
2049                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2050                             packageName, extras, 0 /*flags*/,
2051                             null /*targetPackage*/, null /*finishedReceiver*/,
2052                             updateUsers);
2053                     if (installerPackageName != null) {
2054                         sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2055                                 extras, 0 /*flags*/,
2056                                 installerPackageName, null /*finishedReceiver*/, updateUsers);
2057                     }
2058                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2059                             null /*package*/, null /*extras*/, 0 /*flags*/,
2060                             packageName /*targetPackage*/,
2061                             null /*finishedReceiver*/, updateUsers);
2062                 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2063                     // First-install and we did a restore, so we're responsible for the
2064                     // first-launch broadcast.
2065                     if (DEBUG_BACKUP) {
2066                         Slog.i(TAG, "Post-restore of " + packageName
2067                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2068                     }
2069                     sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2070                 }
2071 
2072                 // Send broadcast package appeared if forward locked/external for all users
2073                 // treat asec-hosted packages like removable media on upgrade
2074                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2075                     if (DEBUG_INSTALL) {
2076                         Slog.i(TAG, "upgrading pkg " + res.pkg
2077                                 + " is ASEC-hosted -> AVAILABLE");
2078                     }
2079                     final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2080                     ArrayList<String> pkgList = new ArrayList<>(1);
2081                     pkgList.add(packageName);
2082                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2083                 }
2084             }
2085 
2086             // Work that needs to happen on first install within each user
2087             if (firstUsers != null && firstUsers.length > 0) {
2088                 synchronized (mPackages) {
2089                     for (int userId : firstUsers) {
2090                         // If this app is a browser and it's newly-installed for some
2091                         // users, clear any default-browser state in those users. The
2092                         // app's nature doesn't depend on the user, so we can just check
2093                         // its browser nature in any user and generalize.
2094                         if (packageIsBrowser(packageName, userId)) {
2095                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2096                         }
2097 
2098                         // We may also need to apply pending (restored) runtime
2099                         // permission grants within these users.
2100                         mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2101                     }
2102                 }
2103             }
2104 
2105             // Log current value of "unknown sources" setting
2106             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2107                     getUnknownSourcesSettings());
2108 
2109             // Remove the replaced package's older resources safely now
2110             // We delete after a gc for applications  on sdcard.
2111             if (res.removedInfo != null && res.removedInfo.args != null) {
2112                 Runtime.getRuntime().gc();
2113                 synchronized (mInstallLock) {
2114                     res.removedInfo.args.doPostDeleteLI(true);
2115                 }
2116             } else {
2117                 // Force a gc to clear up things. Ask for a background one, it's fine to go on
2118                 // and not block here.
2119                 VMRuntime.getRuntime().requestConcurrentGC();
2120             }
2121 
2122             // Notify DexManager that the package was installed for new users.
2123             // The updated users should already be indexed and the package code paths
2124             // should not change.
2125             // Don't notify the manager for ephemeral apps as they are not expected to
2126             // survive long enough to benefit of background optimizations.
2127             for (int userId : firstUsers) {
2128                 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2129                 // There's a race currently where some install events may interleave with an uninstall.
2130                 // This can lead to package info being null (b/36642664).
2131                 if (info != null) {
2132                     mDexManager.notifyPackageInstalled(info, userId);
2133                 }
2134             }
2135         }
2136 
2137         // If someone is watching installs - notify them
2138         if (installObserver != null) {
2139             try {
2140                 Bundle extras = extrasForInstallResult(res);
2141                 installObserver.onPackageInstalled(res.name, res.returnCode,
2142                         res.returnMsg, extras);
2143             } catch (RemoteException e) {
2144                 Slog.i(TAG, "Observer no longer exists.");
2145             }
2146         }
2147     }
2148 
grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( PackageParser.Package pkg)2149     private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2150             PackageParser.Package pkg) {
2151         if (pkg.parentPackage == null) {
2152             return;
2153         }
2154         if (pkg.requestedPermissions == null) {
2155             return;
2156         }
2157         final PackageSetting disabledSysParentPs = mSettings
2158                 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2159         if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2160                 || !disabledSysParentPs.isPrivileged()
2161                 || (disabledSysParentPs.childPackageNames != null
2162                         && !disabledSysParentPs.childPackageNames.isEmpty())) {
2163             return;
2164         }
2165         final int[] allUserIds = sUserManager.getUserIds();
2166         final int permCount = pkg.requestedPermissions.size();
2167         for (int i = 0; i < permCount; i++) {
2168             String permission = pkg.requestedPermissions.get(i);
2169             BasePermission bp = mSettings.mPermissions.get(permission);
2170             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2171                 continue;
2172             }
2173             for (int userId : allUserIds) {
2174                 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2175                         permission, userId)) {
2176                     grantRuntimePermission(pkg.packageName, permission, userId);
2177                 }
2178             }
2179         }
2180     }
2181 
2182     private StorageEventListener mStorageListener = new StorageEventListener() {
2183         @Override
2184         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2185             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2186                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2187                     final String volumeUuid = vol.getFsUuid();
2188 
2189                     // Clean up any users or apps that were removed or recreated
2190                     // while this volume was missing
2191                     sUserManager.reconcileUsers(volumeUuid);
2192                     reconcileApps(volumeUuid);
2193 
2194                     // Clean up any install sessions that expired or were
2195                     // cancelled while this volume was missing
2196                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
2197 
2198                     loadPrivatePackages(vol);
2199 
2200                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2201                     unloadPrivatePackages(vol);
2202                 }
2203             }
2204 
2205             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2206                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
2207                     updateExternalMediaStatus(true, false);
2208                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2209                     updateExternalMediaStatus(false, false);
2210                 }
2211             }
2212         }
2213 
2214         @Override
2215         public void onVolumeForgotten(String fsUuid) {
2216             if (TextUtils.isEmpty(fsUuid)) {
2217                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2218                 return;
2219             }
2220 
2221             // Remove any apps installed on the forgotten volume
2222             synchronized (mPackages) {
2223                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2224                 for (PackageSetting ps : packages) {
2225                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2226                     deletePackageVersioned(new VersionedPackage(ps.name,
2227                             PackageManager.VERSION_CODE_HIGHEST),
2228                             new LegacyPackageDeleteObserver(null).getBinder(),
2229                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2230                     // Try very hard to release any references to this package
2231                     // so we don't risk the system server being killed due to
2232                     // open FDs
2233                     AttributeCache.instance().removePackage(ps.name);
2234                 }
2235 
2236                 mSettings.onVolumeForgotten(fsUuid);
2237                 mSettings.writeLPr();
2238             }
2239         }
2240     };
2241 
grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions)2242     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2243             String[] grantedPermissions) {
2244         for (int userId : userIds) {
2245             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2246         }
2247     }
2248 
grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions)2249     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2250             String[] grantedPermissions) {
2251         PackageSetting ps = (PackageSetting) pkg.mExtras;
2252         if (ps == null) {
2253             return;
2254         }
2255 
2256         PermissionsState permissionsState = ps.getPermissionsState();
2257 
2258         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2259                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2260 
2261         final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2262                 >= Build.VERSION_CODES.M;
2263 
2264         final boolean instantApp = isInstantApp(pkg.packageName, userId);
2265 
2266         for (String permission : pkg.requestedPermissions) {
2267             final BasePermission bp;
2268             synchronized (mPackages) {
2269                 bp = mSettings.mPermissions.get(permission);
2270             }
2271             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2272                     && (!instantApp || bp.isInstant())
2273                     && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2274                     && (grantedPermissions == null
2275                            || ArrayUtils.contains(grantedPermissions, permission))) {
2276                 final int flags = permissionsState.getPermissionFlags(permission, userId);
2277                 if (supportsRuntimePermissions) {
2278                     // Installer cannot change immutable permissions.
2279                     if ((flags & immutableFlags) == 0) {
2280                         grantRuntimePermission(pkg.packageName, permission, userId);
2281                     }
2282                 } else if (mPermissionReviewRequired) {
2283                     // In permission review mode we clear the review flag when we
2284                     // are asked to install the app with all permissions granted.
2285                     if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2286                         updatePermissionFlags(permission, pkg.packageName,
2287                                 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2288                     }
2289                 }
2290             }
2291         }
2292     }
2293 
extrasForInstallResult(PackageInstalledInfo res)2294     Bundle extrasForInstallResult(PackageInstalledInfo res) {
2295         Bundle extras = null;
2296         switch (res.returnCode) {
2297             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2298                 extras = new Bundle();
2299                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2300                         res.origPermission);
2301                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2302                         res.origPackage);
2303                 break;
2304             }
2305             case PackageManager.INSTALL_SUCCEEDED: {
2306                 extras = new Bundle();
2307                 extras.putBoolean(Intent.EXTRA_REPLACING,
2308                         res.removedInfo != null && res.removedInfo.removedPackage != null);
2309                 break;
2310             }
2311         }
2312         return extras;
2313     }
2314 
scheduleWriteSettingsLocked()2315     void scheduleWriteSettingsLocked() {
2316         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2317             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2318         }
2319     }
2320 
scheduleWritePackageListLocked(int userId)2321     void scheduleWritePackageListLocked(int userId) {
2322         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2323             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2324             msg.arg1 = userId;
2325             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2326         }
2327     }
2328 
scheduleWritePackageRestrictionsLocked(UserHandle user)2329     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2330         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2331         scheduleWritePackageRestrictionsLocked(userId);
2332     }
2333 
scheduleWritePackageRestrictionsLocked(int userId)2334     void scheduleWritePackageRestrictionsLocked(int userId) {
2335         final int[] userIds = (userId == UserHandle.USER_ALL)
2336                 ? sUserManager.getUserIds() : new int[]{userId};
2337         for (int nextUserId : userIds) {
2338             if (!sUserManager.exists(nextUserId)) return;
2339             mDirtyUsers.add(nextUserId);
2340             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2341                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2342             }
2343         }
2344     }
2345 
main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)2346     public static PackageManagerService main(Context context, Installer installer,
2347             boolean factoryTest, boolean onlyCore) {
2348         // Self-check for initial settings.
2349         PackageManagerServiceCompilerMapping.checkProperties();
2350 
2351         PackageManagerService m = new PackageManagerService(context, installer,
2352                 factoryTest, onlyCore);
2353         m.enableSystemUserPackages();
2354         ServiceManager.addService("package", m);
2355         final PackageManagerNative pmn = m.new PackageManagerNative();
2356         ServiceManager.addService("package_native", pmn);
2357         return m;
2358     }
2359 
enableSystemUserPackages()2360     private void enableSystemUserPackages() {
2361         if (!UserManager.isSplitSystemUser()) {
2362             return;
2363         }
2364         // For system user, enable apps based on the following conditions:
2365         // - app is whitelisted or belong to one of these groups:
2366         //   -- system app which has no launcher icons
2367         //   -- system app which has INTERACT_ACROSS_USERS permission
2368         //   -- system IME app
2369         // - app is not in the blacklist
2370         AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2371         Set<String> enableApps = new ArraySet<>();
2372         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2373                 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2374                 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2375         ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2376         enableApps.addAll(wlApps);
2377         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2378                 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2379         ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2380         enableApps.removeAll(blApps);
2381         Log.i(TAG, "Applications installed for system user: " + enableApps);
2382         List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2383                 UserHandle.SYSTEM);
2384         final int allAppsSize = allAps.size();
2385         synchronized (mPackages) {
2386             for (int i = 0; i < allAppsSize; i++) {
2387                 String pName = allAps.get(i);
2388                 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2389                 // Should not happen, but we shouldn't be failing if it does
2390                 if (pkgSetting == null) {
2391                     continue;
2392                 }
2393                 boolean install = enableApps.contains(pName);
2394                 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2395                     Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2396                             + " for system user");
2397                     pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2398                 }
2399             }
2400             scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2401         }
2402     }
2403 
getDefaultDisplayMetrics(Context context, DisplayMetrics metrics)2404     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2405         DisplayManager displayManager = (DisplayManager) context.getSystemService(
2406                 Context.DISPLAY_SERVICE);
2407         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2408     }
2409 
2410     /**
2411      * Requests that files preopted on a secondary system partition be copied to the data partition
2412      * if possible.  Note that the actual copying of the files is accomplished by init for security
2413      * reasons. This simply requests that the copy takes place and awaits confirmation of its
2414      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2415      */
requestCopyPreoptedFiles()2416     private static void requestCopyPreoptedFiles() {
2417         final int WAIT_TIME_MS = 100;
2418         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2419         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2420             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2421             // We will wait for up to 100 seconds.
2422             final long timeStart = SystemClock.uptimeMillis();
2423             final long timeEnd = timeStart + 100 * 1000;
2424             long timeNow = timeStart;
2425             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2426                 try {
2427                     Thread.sleep(WAIT_TIME_MS);
2428                 } catch (InterruptedException e) {
2429                     // Do nothing
2430                 }
2431                 timeNow = SystemClock.uptimeMillis();
2432                 if (timeNow > timeEnd) {
2433                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2434                     Slog.wtf(TAG, "cppreopt did not finish!");
2435                     break;
2436                 }
2437             }
2438 
2439             Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2440         }
2441     }
2442 
PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)2443     public PackageManagerService(Context context, Installer installer,
2444             boolean factoryTest, boolean onlyCore) {
2445         LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2446         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2447         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2448                 SystemClock.uptimeMillis());
2449 
2450         if (mSdkVersion <= 0) {
2451             Slog.w(TAG, "**** ro.build.version.sdk not set!");
2452         }
2453 
2454         mContext = context;
2455 
2456         mPermissionReviewRequired = context.getResources().getBoolean(
2457                 R.bool.config_permissionReviewRequired);
2458 
2459         mFactoryTest = factoryTest;
2460         mOnlyCore = onlyCore;
2461         mMetrics = new DisplayMetrics();
2462         mSettings = new Settings(mPackages);
2463         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2464                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2465         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2466                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2467         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2468                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2469         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2470                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2471         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2472                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2473         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2474                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2475 
2476         String separateProcesses = SystemProperties.get("debug.separate_processes");
2477         if (separateProcesses != null && separateProcesses.length() > 0) {
2478             if ("*".equals(separateProcesses)) {
2479                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2480                 mSeparateProcesses = null;
2481                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2482             } else {
2483                 mDefParseFlags = 0;
2484                 mSeparateProcesses = separateProcesses.split(",");
2485                 Slog.w(TAG, "Running with debug.separate_processes: "
2486                         + separateProcesses);
2487             }
2488         } else {
2489             mDefParseFlags = 0;
2490             mSeparateProcesses = null;
2491         }
2492 
2493         mInstaller = installer;
2494         mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2495                 "*dexopt*");
2496         mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2497         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2498 
2499         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2500                 FgThread.get().getLooper());
2501 
2502         getDefaultDisplayMetrics(context, mMetrics);
2503 
2504         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2505         SystemConfig systemConfig = SystemConfig.getInstance();
2506         mGlobalGids = systemConfig.getGlobalGids();
2507         mSystemPermissions = systemConfig.getSystemPermissions();
2508         mAvailableFeatures = systemConfig.getAvailableFeatures();
2509         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2510 
2511         mProtectedPackages = new ProtectedPackages(mContext);
2512 
2513         synchronized (mInstallLock) {
2514         // writer
2515         synchronized (mPackages) {
2516             mHandlerThread = new ServiceThread(TAG,
2517                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2518             mHandlerThread.start();
2519             mHandler = new PackageHandler(mHandlerThread.getLooper());
2520             mProcessLoggingHandler = new ProcessLoggingHandler();
2521             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2522 
2523             mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2524             mInstantAppRegistry = new InstantAppRegistry(this);
2525 
2526             File dataDir = Environment.getDataDirectory();
2527             mAppInstallDir = new File(dataDir, "app");
2528             mAppLib32InstallDir = new File(dataDir, "app-lib");
2529             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2530             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2531             sUserManager = new UserManagerService(context, this,
2532                     new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2533 
2534             // Propagate permission configuration in to package manager.
2535             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2536                     = systemConfig.getPermissions();
2537             for (int i=0; i<permConfig.size(); i++) {
2538                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2539                 BasePermission bp = mSettings.mPermissions.get(perm.name);
2540                 if (bp == null) {
2541                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2542                     mSettings.mPermissions.put(perm.name, bp);
2543                 }
2544                 if (perm.gids != null) {
2545                     bp.setGids(perm.gids, perm.perUser);
2546                 }
2547             }
2548 
2549             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2550             final int builtInLibCount = libConfig.size();
2551             for (int i = 0; i < builtInLibCount; i++) {
2552                 String name = libConfig.keyAt(i);
2553                 String path = libConfig.valueAt(i);
2554                 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2555                         SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2556             }
2557 
2558             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2559 
2560             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2561             mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2562             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2563 
2564             // Clean up orphaned packages for which the code path doesn't exist
2565             // and they are an update to a system app - caused by bug/32321269
2566             final int packageSettingCount = mSettings.mPackages.size();
2567             for (int i = packageSettingCount - 1; i >= 0; i--) {
2568                 PackageSetting ps = mSettings.mPackages.valueAt(i);
2569                 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2570                         && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2571                     mSettings.mPackages.removeAt(i);
2572                     mSettings.enableSystemPackageLPw(ps.name);
2573                 }
2574             }
2575 
2576             if (mFirstBoot) {
2577                 requestCopyPreoptedFiles();
2578             }
2579 
2580             String customResolverActivity = Resources.getSystem().getString(
2581                     R.string.config_customResolverActivity);
2582             if (TextUtils.isEmpty(customResolverActivity)) {
2583                 customResolverActivity = null;
2584             } else {
2585                 mCustomResolverComponentName = ComponentName.unflattenFromString(
2586                         customResolverActivity);
2587             }
2588 
2589             long startTime = SystemClock.uptimeMillis();
2590 
2591             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2592                     startTime);
2593 
2594             final String bootClassPath = System.getenv("BOOTCLASSPATH");
2595             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2596 
2597             if (bootClassPath == null) {
2598                 Slog.w(TAG, "No BOOTCLASSPATH found!");
2599             }
2600 
2601             if (systemServerClassPath == null) {
2602                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2603             }
2604 
2605             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2606 
2607             final VersionInfo ver = mSettings.getInternalVersion();
2608             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2609             if (mIsUpgrade) {
2610                 logCriticalInfo(Log.INFO,
2611                         "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2612             }
2613 
2614             // when upgrading from pre-M, promote system app permissions from install to runtime
2615             mPromoteSystemApps =
2616                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2617 
2618             // When upgrading from pre-N, we need to handle package extraction like first boot,
2619             // as there is no profiling data available.
2620             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2621 
2622             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2623 
2624             // save off the names of pre-existing system packages prior to scanning; we don't
2625             // want to automatically grant runtime permissions for new system apps
2626             if (mPromoteSystemApps) {
2627                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2628                 while (pkgSettingIter.hasNext()) {
2629                     PackageSetting ps = pkgSettingIter.next();
2630                     if (isSystemApp(ps)) {
2631                         mExistingSystemPackages.add(ps.name);
2632                     }
2633                 }
2634             }
2635 
2636             mCacheDir = preparePackageParserCache(mIsUpgrade);
2637 
2638             // Set flag to monitor and not change apk file paths when
2639             // scanning install directories.
2640             int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2641 
2642             if (mIsUpgrade || mFirstBoot) {
2643                 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2644             }
2645 
2646             // Collect vendor overlay packages. (Do this before scanning any apps.)
2647             // For security and version matching reason, only consider
2648             // overlay packages if they reside in the right directory.
2649             scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2650                     | PackageParser.PARSE_IS_SYSTEM
2651                     | PackageParser.PARSE_IS_SYSTEM_DIR
2652                     | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2653 
2654             mParallelPackageParserCallback.findStaticOverlayPackages();
2655 
2656             // Find base frameworks (resource packages without code).
2657             scanDirTracedLI(frameworkDir, mDefParseFlags
2658                     | PackageParser.PARSE_IS_SYSTEM
2659                     | PackageParser.PARSE_IS_SYSTEM_DIR
2660                     | PackageParser.PARSE_IS_PRIVILEGED,
2661                     scanFlags | SCAN_NO_DEX, 0);
2662 
2663             // Collected privileged system packages.
2664             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2665             scanDirTracedLI(privilegedAppDir, mDefParseFlags
2666                     | PackageParser.PARSE_IS_SYSTEM
2667                     | PackageParser.PARSE_IS_SYSTEM_DIR
2668                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2669 
2670             // Collect ordinary system packages.
2671             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2672             scanDirTracedLI(systemAppDir, mDefParseFlags
2673                     | PackageParser.PARSE_IS_SYSTEM
2674                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2675 
2676             // Collect all vendor packages.
2677             File vendorAppDir = new File("/vendor/app");
2678             try {
2679                 vendorAppDir = vendorAppDir.getCanonicalFile();
2680             } catch (IOException e) {
2681                 // failed to look up canonical path, continue with original one
2682             }
2683             scanDirTracedLI(vendorAppDir, mDefParseFlags
2684                     | PackageParser.PARSE_IS_SYSTEM
2685                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2686 
2687             // Collect all OEM packages.
2688             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2689             scanDirTracedLI(oemAppDir, mDefParseFlags
2690                     | PackageParser.PARSE_IS_SYSTEM
2691                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2692 
2693             // Prune any system packages that no longer exist.
2694             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2695             // Stub packages must either be replaced with full versions in the /data
2696             // partition or be disabled.
2697             final List<String> stubSystemApps = new ArrayList<>();
2698             if (!mOnlyCore) {
2699                 // do this first before mucking with mPackages for the "expecting better" case
2700                 final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2701                 while (pkgIterator.hasNext()) {
2702                     final PackageParser.Package pkg = pkgIterator.next();
2703                     if (pkg.isStub) {
2704                         stubSystemApps.add(pkg.packageName);
2705                     }
2706                 }
2707 
2708                 final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2709                 while (psit.hasNext()) {
2710                     PackageSetting ps = psit.next();
2711 
2712                     /*
2713                      * If this is not a system app, it can't be a
2714                      * disable system app.
2715                      */
2716                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2717                         continue;
2718                     }
2719 
2720                     /*
2721                      * If the package is scanned, it's not erased.
2722                      */
2723                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2724                     if (scannedPkg != null) {
2725                         /*
2726                          * If the system app is both scanned and in the
2727                          * disabled packages list, then it must have been
2728                          * added via OTA. Remove it from the currently
2729                          * scanned package so the previously user-installed
2730                          * application can be scanned.
2731                          */
2732                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2733                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2734                                     + ps.name + "; removing system app.  Last known codePath="
2735                                     + ps.codePathString + ", installStatus=" + ps.installStatus
2736                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2737                                     + scannedPkg.mVersionCode);
2738                             removePackageLI(scannedPkg, true);
2739                             mExpectingBetter.put(ps.name, ps.codePath);
2740                         }
2741 
2742                         continue;
2743                     }
2744 
2745                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2746                         psit.remove();
2747                         logCriticalInfo(Log.WARN, "System package " + ps.name
2748                                 + " no longer exists; it's data will be wiped");
2749                         // Actual deletion of code and data will be handled by later
2750                         // reconciliation step
2751                     } else {
2752                         // we still have a disabled system package, but, it still might have
2753                         // been removed. check the code path still exists and check there's
2754                         // still a package. the latter can happen if an OTA keeps the same
2755                         // code path, but, changes the package name.
2756                         final PackageSetting disabledPs =
2757                                 mSettings.getDisabledSystemPkgLPr(ps.name);
2758                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2759                                 || disabledPs.pkg == null) {
2760                             possiblyDeletedUpdatedSystemApps.add(ps.name);
2761                         }
2762                     }
2763                 }
2764             }
2765 
2766             //look for any incomplete package installations
2767             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2768             for (int i = 0; i < deletePkgsList.size(); i++) {
2769                 // Actual deletion of code and data will be handled by later
2770                 // reconciliation step
2771                 final String packageName = deletePkgsList.get(i).name;
2772                 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2773                 synchronized (mPackages) {
2774                     mSettings.removePackageLPw(packageName);
2775                 }
2776             }
2777 
2778             //delete tmp files
2779             deleteTempPackageFiles();
2780 
2781             final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2782 
2783             // Remove any shared userIDs that have no associated packages
2784             mSettings.pruneSharedUsersLPw();
2785             final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2786             final int systemPackagesCount = mPackages.size();
2787             Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2788                     + " ms, packageCount: " + systemPackagesCount
2789                     + " , timePerPackage: "
2790                     + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2791                     + " , cached: " + cachedSystemApps);
2792             if (mIsUpgrade && systemPackagesCount > 0) {
2793                 MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2794                         ((int) systemScanTime) / systemPackagesCount);
2795             }
2796             if (!mOnlyCore) {
2797                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2798                         SystemClock.uptimeMillis());
2799                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2800 
2801                 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2802                         | PackageParser.PARSE_FORWARD_LOCK,
2803                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2804 
2805                 // Remove disable package settings for updated system apps that were
2806                 // removed via an OTA. If the update is no longer present, remove the
2807                 // app completely. Otherwise, revoke their system privileges.
2808                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2809                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2810                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2811 
2812                     final String msg;
2813                     if (deletedPkg == null) {
2814                         // should have found an update, but, we didn't; remove everything
2815                         msg = "Updated system package " + deletedAppName
2816                                 + " no longer exists; removing its data";
2817                         // Actual deletion of code and data will be handled by later
2818                         // reconciliation step
2819                     } else {
2820                         // found an update; revoke system privileges
2821                         msg = "Updated system package + " + deletedAppName
2822                                 + " no longer exists; revoking system privileges";
2823 
2824                         // Don't do anything if a stub is removed from the system image. If
2825                         // we were to remove the uncompressed version from the /data partition,
2826                         // this is where it'd be done.
2827 
2828                         final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2829                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2830                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2831                     }
2832                     logCriticalInfo(Log.WARN, msg);
2833                 }
2834 
2835                 /*
2836                  * Make sure all system apps that we expected to appear on
2837                  * the userdata partition actually showed up. If they never
2838                  * appeared, crawl back and revive the system version.
2839                  */
2840                 for (int i = 0; i < mExpectingBetter.size(); i++) {
2841                     final String packageName = mExpectingBetter.keyAt(i);
2842                     if (!mPackages.containsKey(packageName)) {
2843                         final File scanFile = mExpectingBetter.valueAt(i);
2844 
2845                         logCriticalInfo(Log.WARN, "Expected better " + packageName
2846                                 + " but never showed up; reverting to system");
2847 
2848                         int reparseFlags = mDefParseFlags;
2849                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
2850                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2851                                     | PackageParser.PARSE_IS_SYSTEM_DIR
2852                                     | PackageParser.PARSE_IS_PRIVILEGED;
2853                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
2854                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2855                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2856                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2857                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2858                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2859                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
2860                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2861                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2862                         } else {
2863                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2864                             continue;
2865                         }
2866 
2867                         mSettings.enableSystemPackageLPw(packageName);
2868 
2869                         try {
2870                             scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2871                         } catch (PackageManagerException e) {
2872                             Slog.e(TAG, "Failed to parse original system package: "
2873                                     + e.getMessage());
2874                         }
2875                     }
2876                 }
2877 
2878                 // Uncompress and install any stubbed system applications.
2879                 // This must be done last to ensure all stubs are replaced or disabled.
2880                 decompressSystemApplications(stubSystemApps, scanFlags);
2881 
2882                 final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2883                                 - cachedSystemApps;
2884 
2885                 final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2886                 final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2887                 Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2888                         + " ms, packageCount: " + dataPackagesCount
2889                         + " , timePerPackage: "
2890                         + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2891                         + " , cached: " + cachedNonSystemApps);
2892                 if (mIsUpgrade && dataPackagesCount > 0) {
2893                     MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2894                             ((int) dataScanTime) / dataPackagesCount);
2895                 }
2896             }
2897             mExpectingBetter.clear();
2898 
2899             // Resolve the storage manager.
2900             mStorageManagerPackage = getStorageManagerPackageName();
2901 
2902             // Resolve protected action filters. Only the setup wizard is allowed to
2903             // have a high priority filter for these actions.
2904             mSetupWizardPackage = getSetupWizardPackageName();
2905             if (mProtectedFilters.size() > 0) {
2906                 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2907                     Slog.i(TAG, "No setup wizard;"
2908                         + " All protected intents capped to priority 0");
2909                 }
2910                 for (ActivityIntentInfo filter : mProtectedFilters) {
2911                     if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2912                         if (DEBUG_FILTERS) {
2913                             Slog.i(TAG, "Found setup wizard;"
2914                                 + " allow priority " + filter.getPriority() + ";"
2915                                 + " package: " + filter.activity.info.packageName
2916                                 + " activity: " + filter.activity.className
2917                                 + " priority: " + filter.getPriority());
2918                         }
2919                         // skip setup wizard; allow it to keep the high priority filter
2920                         continue;
2921                     }
2922                     if (DEBUG_FILTERS) {
2923                         Slog.i(TAG, "Protected action; cap priority to 0;"
2924                                 + " package: " + filter.activity.info.packageName
2925                                 + " activity: " + filter.activity.className
2926                                 + " origPrio: " + filter.getPriority());
2927                     }
2928                     filter.setPriority(0);
2929                 }
2930             }
2931             mDeferProtectedFilters = false;
2932             mProtectedFilters.clear();
2933 
2934             // Now that we know all of the shared libraries, update all clients to have
2935             // the correct library paths.
2936             updateAllSharedLibrariesLPw(null);
2937 
2938             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2939                 // NOTE: We ignore potential failures here during a system scan (like
2940                 // the rest of the commands above) because there's precious little we
2941                 // can do about it. A settings error is reported, though.
2942                 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2943             }
2944 
2945             // Now that we know all the packages we are keeping,
2946             // read and update their last usage times.
2947             mPackageUsage.read(mPackages);
2948             mCompilerStats.read();
2949 
2950             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2951                     SystemClock.uptimeMillis());
2952             Slog.i(TAG, "Time to scan packages: "
2953                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
2954                     + " seconds");
2955 
2956             // If the platform SDK has changed since the last time we booted,
2957             // we need to re-grant app permission to catch any new ones that
2958             // appear.  This is really a hack, and means that apps can in some
2959             // cases get permissions that the user didn't initially explicitly
2960             // allow...  it would be nice to have some better way to handle
2961             // this situation.
2962             int updateFlags = UPDATE_PERMISSIONS_ALL;
2963             if (ver.sdkVersion != mSdkVersion) {
2964                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2965                         + mSdkVersion + "; regranting permissions for internal storage");
2966                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2967             }
2968             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2969             ver.sdkVersion = mSdkVersion;
2970 
2971             // If this is the first boot or an update from pre-M, and it is a normal
2972             // boot, then we need to initialize the default preferred apps across
2973             // all defined users.
2974             if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2975                 for (UserInfo user : sUserManager.getUsers(true)) {
2976                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2977                     applyFactoryDefaultBrowserLPw(user.id);
2978                     primeDomainVerificationsLPw(user.id);
2979                 }
2980             }
2981 
2982             // Prepare storage for system user really early during boot,
2983             // since core system apps like SettingsProvider and SystemUI
2984             // can't wait for user to start
2985             final int storageFlags;
2986             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2987                 storageFlags = StorageManager.FLAG_STORAGE_DE;
2988             } else {
2989                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2990             }
2991             List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2992                     UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2993                     true /* onlyCoreApps */);
2994             mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2995                 TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2996                         Trace.TRACE_TAG_PACKAGE_MANAGER);
2997                 traceLog.traceBegin("AppDataFixup");
2998                 try {
2999                     mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3000                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3001                 } catch (InstallerException e) {
3002                     Slog.w(TAG, "Trouble fixing GIDs", e);
3003                 }
3004                 traceLog.traceEnd();
3005 
3006                 traceLog.traceBegin("AppDataPrepare");
3007                 if (deferPackages == null || deferPackages.isEmpty()) {
3008                     return;
3009                 }
3010                 int count = 0;
3011                 for (String pkgName : deferPackages) {
3012                     PackageParser.Package pkg = null;
3013                     synchronized (mPackages) {
3014                         PackageSetting ps = mSettings.getPackageLPr(pkgName);
3015                         if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3016                             pkg = ps.pkg;
3017                         }
3018                     }
3019                     if (pkg != null) {
3020                         synchronized (mInstallLock) {
3021                             prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3022                                     true /* maybeMigrateAppData */);
3023                         }
3024                         count++;
3025                     }
3026                 }
3027                 traceLog.traceEnd();
3028                 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3029             }, "prepareAppData");
3030 
3031             // If this is first boot after an OTA, and a normal boot, then
3032             // we need to clear code cache directories.
3033             // Note that we do *not* clear the application profiles. These remain valid
3034             // across OTAs and are used to drive profile verification (post OTA) and
3035             // profile compilation (without waiting to collect a fresh set of profiles).
3036             if (mIsUpgrade && !onlyCore) {
3037                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3038                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
3039                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
3040                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3041                         // No apps are running this early, so no need to freeze
3042                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3043                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3044                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3045                     }
3046                 }
3047                 ver.fingerprint = Build.FINGERPRINT;
3048             }
3049 
3050             checkDefaultBrowser();
3051 
3052             // clear only after permissions and other defaults have been updated
3053             mExistingSystemPackages.clear();
3054             mPromoteSystemApps = false;
3055 
3056             // All the changes are done during package scanning.
3057             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3058 
3059             // can downgrade to reader
3060             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3061             mSettings.writeLPr();
3062             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3063             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3064                     SystemClock.uptimeMillis());
3065 
3066             if (!mOnlyCore) {
3067                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3068                 mRequiredInstallerPackage = getRequiredInstallerLPr();
3069                 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3070                 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3071                 if (mIntentFilterVerifierComponent != null) {
3072                     mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3073                             mIntentFilterVerifierComponent);
3074                 } else {
3075                     mIntentFilterVerifier = null;
3076                 }
3077                 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3078                         PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3079                         SharedLibraryInfo.VERSION_UNDEFINED);
3080                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3081                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3082                         SharedLibraryInfo.VERSION_UNDEFINED);
3083             } else {
3084                 mRequiredVerifierPackage = null;
3085                 mRequiredInstallerPackage = null;
3086                 mRequiredUninstallerPackage = null;
3087                 mIntentFilterVerifierComponent = null;
3088                 mIntentFilterVerifier = null;
3089                 mServicesSystemSharedLibraryPackageName = null;
3090                 mSharedSystemSharedLibraryPackageName = null;
3091             }
3092 
3093             mInstallerService = new PackageInstallerService(context, this);
3094             final Pair<ComponentName, String> instantAppResolverComponent =
3095                     getInstantAppResolverLPr();
3096             if (instantAppResolverComponent != null) {
3097                 if (DEBUG_EPHEMERAL) {
3098                     Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3099                 }
3100                 mInstantAppResolverConnection = new EphemeralResolverConnection(
3101                         mContext, instantAppResolverComponent.first,
3102                         instantAppResolverComponent.second);
3103                 mInstantAppResolverSettingsComponent =
3104                         getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3105             } else {
3106                 mInstantAppResolverConnection = null;
3107                 mInstantAppResolverSettingsComponent = null;
3108             }
3109             updateInstantAppInstallerLocked(null);
3110 
3111             // Read and update the usage of dex files.
3112             // Do this at the end of PM init so that all the packages have their
3113             // data directory reconciled.
3114             // At this point we know the code paths of the packages, so we can validate
3115             // the disk file and build the internal cache.
3116             // The usage file is expected to be small so loading and verifying it
3117             // should take a fairly small time compare to the other activities (e.g. package
3118             // scanning).
3119             final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3120             final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3121             for (int userId : currentUserIds) {
3122                 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3123             }
3124             mDexManager.load(userPackages);
3125             if (mIsUpgrade) {
3126                 MetricsLogger.histogram(null, "ota_package_manager_init_time",
3127                         (int) (SystemClock.uptimeMillis() - startTime));
3128             }
3129         } // synchronized (mPackages)
3130         } // synchronized (mInstallLock)
3131 
3132         // Now after opening every single application zip, make sure they
3133         // are all flushed.  Not really needed, but keeps things nice and
3134         // tidy.
3135         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3136         Runtime.getRuntime().gc();
3137         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3138 
3139         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3140         FallbackCategoryProvider.loadFallbacks();
3141         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3142 
3143         // The initial scanning above does many calls into installd while
3144         // holding the mPackages lock, but we're mostly interested in yelling
3145         // once we have a booted system.
3146         mInstaller.setWarnIfHeld(mPackages);
3147 
3148         // Expose private service for system components to use.
3149         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3150         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3151     }
3152 
3153     /**
3154      * Uncompress and install stub applications.
3155      * <p>In order to save space on the system partition, some applications are shipped in a
3156      * compressed form. In addition the compressed bits for the full application, the
3157      * system image contains a tiny stub comprised of only the Android manifest.
3158      * <p>During the first boot, attempt to uncompress and install the full application. If
3159      * the application can't be installed for any reason, disable the stub and prevent
3160      * uncompressing the full application during future boots.
3161      * <p>In order to forcefully attempt an installation of a full application, go to app
3162      * settings and enable the application.
3163      */
decompressSystemApplications(@onNull List<String> stubSystemApps, int scanFlags)3164     private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3165         for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3166             final String pkgName = stubSystemApps.get(i);
3167             // skip if the system package is already disabled
3168             if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3169                 stubSystemApps.remove(i);
3170                 continue;
3171             }
3172             // skip if the package isn't installed (?!); this should never happen
3173             final PackageParser.Package pkg = mPackages.get(pkgName);
3174             if (pkg == null) {
3175                 stubSystemApps.remove(i);
3176                 continue;
3177             }
3178             // skip if the package has been disabled by the user
3179             final PackageSetting ps = mSettings.mPackages.get(pkgName);
3180             if (ps != null) {
3181                 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3182                 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3183                     stubSystemApps.remove(i);
3184                     continue;
3185                 }
3186             }
3187 
3188             if (DEBUG_COMPRESSION) {
3189                 Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3190             }
3191 
3192             // uncompress the binary to its eventual destination on /data
3193             final File scanFile = decompressPackage(pkg);
3194             if (scanFile == null) {
3195                 continue;
3196             }
3197 
3198             // install the package to replace the stub on /system
3199             try {
3200                 mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3201                 removePackageLI(pkg, true /*chatty*/);
3202                 scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3203                 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3204                         UserHandle.USER_SYSTEM, "android");
3205                 stubSystemApps.remove(i);
3206                 continue;
3207             } catch (PackageManagerException e) {
3208                 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3209             }
3210 
3211             // any failed attempt to install the package will be cleaned up later
3212         }
3213 
3214         // disable any stub still left; these failed to install the full application
3215         for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3216             final String pkgName = stubSystemApps.get(i);
3217             final PackageSetting ps = mSettings.mPackages.get(pkgName);
3218             ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3219                     UserHandle.USER_SYSTEM, "android");
3220             logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3221         }
3222     }
3223 
decompressFile(File srcFile, File dstFile)3224     private int decompressFile(File srcFile, File dstFile) throws ErrnoException {
3225         if (DEBUG_COMPRESSION) {
3226             Slog.i(TAG, "Decompress file"
3227                     + "; src: " + srcFile.getAbsolutePath()
3228                     + ", dst: " + dstFile.getAbsolutePath());
3229         }
3230         try (
3231                 InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
3232                 OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
3233         ) {
3234             Streams.copy(fileIn, fileOut);
3235             Os.chmod(dstFile.getAbsolutePath(), 0644);
3236             return PackageManager.INSTALL_SUCCEEDED;
3237         } catch (IOException e) {
3238             logCriticalInfo(Log.ERROR, "Failed to decompress file"
3239                     + "; src: " + srcFile.getAbsolutePath()
3240                     + ", dst: " + dstFile.getAbsolutePath());
3241         }
3242         return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3243     }
3244 
getCompressedFiles(String codePath)3245     private File[] getCompressedFiles(String codePath) {
3246         final File stubCodePath = new File(codePath);
3247         final String stubName = stubCodePath.getName();
3248 
3249         // The layout of a compressed package on a given partition is as follows :
3250         //
3251         // Compressed artifacts:
3252         //
3253         // /partition/ModuleName/foo.gz
3254         // /partation/ModuleName/bar.gz
3255         //
3256         // Stub artifact:
3257         //
3258         // /partition/ModuleName-Stub/ModuleName-Stub.apk
3259         //
3260         // In other words, stub is on the same partition as the compressed artifacts
3261         // and in a directory that's suffixed with "-Stub".
3262         int idx = stubName.lastIndexOf(STUB_SUFFIX);
3263         if (idx < 0 || (stubName.length() != (idx + STUB_SUFFIX.length()))) {
3264             return null;
3265         }
3266 
3267         final File stubParentDir = stubCodePath.getParentFile();
3268         if (stubParentDir == null) {
3269             Slog.e(TAG, "Unable to determine stub parent dir for codePath: " + codePath);
3270             return null;
3271         }
3272 
3273         final File compressedPath = new File(stubParentDir, stubName.substring(0, idx));
3274         final File[] files = compressedPath.listFiles(new FilenameFilter() {
3275             @Override
3276             public boolean accept(File dir, String name) {
3277                 return name.toLowerCase().endsWith(COMPRESSED_EXTENSION);
3278             }
3279         });
3280 
3281         if (DEBUG_COMPRESSION && files != null && files.length > 0) {
3282             Slog.i(TAG, "getCompressedFiles[" + codePath + "]: " + Arrays.toString(files));
3283         }
3284 
3285         return files;
3286     }
3287 
compressedFileExists(String codePath)3288     private boolean compressedFileExists(String codePath) {
3289         final File[] compressedFiles = getCompressedFiles(codePath);
3290         return compressedFiles != null && compressedFiles.length > 0;
3291     }
3292 
3293     /**
3294      * Decompresses the given package on the system image onto
3295      * the /data partition.
3296      * @return The directory the package was decompressed into. Otherwise, {@code null}.
3297      */
decompressPackage(PackageParser.Package pkg)3298     private File decompressPackage(PackageParser.Package pkg) {
3299         final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3300         if (compressedFiles == null || compressedFiles.length == 0) {
3301             if (DEBUG_COMPRESSION) {
3302                 Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3303             }
3304             return null;
3305         }
3306         final File dstCodePath =
3307                 getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3308         int ret = PackageManager.INSTALL_SUCCEEDED;
3309         try {
3310             Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3311             Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3312             for (File srcFile : compressedFiles) {
3313                 final String srcFileName = srcFile.getName();
3314                 final String dstFileName = srcFileName.substring(
3315                         0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3316                 final File dstFile = new File(dstCodePath, dstFileName);
3317                 ret = decompressFile(srcFile, dstFile);
3318                 if (ret != PackageManager.INSTALL_SUCCEEDED) {
3319                     logCriticalInfo(Log.ERROR, "Failed to decompress"
3320                             + "; pkg: " + pkg.packageName
3321                             + ", file: " + dstFileName);
3322                     break;
3323                 }
3324             }
3325         } catch (ErrnoException e) {
3326             logCriticalInfo(Log.ERROR, "Failed to decompress"
3327                     + "; pkg: " + pkg.packageName
3328                     + ", err: " + e.errno);
3329         }
3330         if (ret == PackageManager.INSTALL_SUCCEEDED) {
3331             final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3332             NativeLibraryHelper.Handle handle = null;
3333             try {
3334                 handle = NativeLibraryHelper.Handle.create(dstCodePath);
3335                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3336                         null /*abiOverride*/);
3337             } catch (IOException e) {
3338                 logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3339                         + "; pkg: " + pkg.packageName);
3340                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3341             } finally {
3342                 IoUtils.closeQuietly(handle);
3343             }
3344         }
3345         if (ret != PackageManager.INSTALL_SUCCEEDED) {
3346             if (dstCodePath == null || !dstCodePath.exists()) {
3347                 return null;
3348             }
3349             removeCodePathLI(dstCodePath);
3350             return null;
3351         }
3352 
3353         return dstCodePath;
3354     }
3355 
updateInstantAppInstallerLocked(String modifiedPackage)3356     private void updateInstantAppInstallerLocked(String modifiedPackage) {
3357         // we're only interested in updating the installer appliction when 1) it's not
3358         // already set or 2) the modified package is the installer
3359         if (mInstantAppInstallerActivity != null
3360                 && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3361                         .equals(modifiedPackage)) {
3362             return;
3363         }
3364         setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3365     }
3366 
preparePackageParserCache(boolean isUpgrade)3367     private static File preparePackageParserCache(boolean isUpgrade) {
3368         if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3369             return null;
3370         }
3371 
3372         // Disable package parsing on eng builds to allow for faster incremental development.
3373         if (Build.IS_ENG) {
3374             return null;
3375         }
3376 
3377         if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3378             Slog.i(TAG, "Disabling package parser cache due to system property.");
3379             return null;
3380         }
3381 
3382         // The base directory for the package parser cache lives under /data/system/.
3383         final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3384                 "package_cache");
3385         if (cacheBaseDir == null) {
3386             return null;
3387         }
3388 
3389         // If this is a system upgrade scenario, delete the contents of the package cache dir.
3390         // This also serves to "GC" unused entries when the package cache version changes (which
3391         // can only happen during upgrades).
3392         if (isUpgrade) {
3393             FileUtils.deleteContents(cacheBaseDir);
3394         }
3395 
3396 
3397         // Return the versioned package cache directory. This is something like
3398         // "/data/system/package_cache/1"
3399         File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3400 
3401         // The following is a workaround to aid development on non-numbered userdebug
3402         // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3403         // the system partition is newer.
3404         //
3405         // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3406         // that starts with "eng." to signify that this is an engineering build and not
3407         // destined for release.
3408         if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3409             Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3410 
3411             // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3412             // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3413             // in general and should not be used for production changes. In this specific case,
3414             // we know that they will work.
3415             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3416             if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3417                 FileUtils.deleteContents(cacheBaseDir);
3418                 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3419             }
3420         }
3421 
3422         return cacheDir;
3423     }
3424 
3425     @Override
isFirstBoot()3426     public boolean isFirstBoot() {
3427         // allow instant applications
3428         return mFirstBoot;
3429     }
3430 
3431     @Override
isOnlyCoreApps()3432     public boolean isOnlyCoreApps() {
3433         // allow instant applications
3434         return mOnlyCore;
3435     }
3436 
3437     @Override
isUpgrade()3438     public boolean isUpgrade() {
3439         // allow instant applications
3440         return mIsUpgrade;
3441     }
3442 
getRequiredButNotReallyRequiredVerifierLPr()3443     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3444         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3445 
3446         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3447                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3448                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3449         if (matches.size() == 1) {
3450             return matches.get(0).getComponentInfo().packageName;
3451         } else if (matches.size() == 0) {
3452             Log.e(TAG, "There should probably be a verifier, but, none were found");
3453             return null;
3454         }
3455         throw new RuntimeException("There must be exactly one verifier; found " + matches);
3456     }
3457 
getRequiredSharedLibraryLPr(String name, int version)3458     private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3459         synchronized (mPackages) {
3460             SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3461             if (libraryEntry == null) {
3462                 throw new IllegalStateException("Missing required shared library:" + name);
3463             }
3464             return libraryEntry.apk;
3465         }
3466     }
3467 
getRequiredInstallerLPr()3468     private @NonNull String getRequiredInstallerLPr() {
3469         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3470         intent.addCategory(Intent.CATEGORY_DEFAULT);
3471         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3472 
3473         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3474                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3475                 UserHandle.USER_SYSTEM);
3476         if (matches.size() == 1) {
3477             ResolveInfo resolveInfo = matches.get(0);
3478             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3479                 throw new RuntimeException("The installer must be a privileged app");
3480             }
3481             return matches.get(0).getComponentInfo().packageName;
3482         } else {
3483             throw new RuntimeException("There must be exactly one installer; found " + matches);
3484         }
3485     }
3486 
getRequiredUninstallerLPr()3487     private @NonNull String getRequiredUninstallerLPr() {
3488         final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3489         intent.addCategory(Intent.CATEGORY_DEFAULT);
3490         intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3491 
3492         final ResolveInfo resolveInfo = resolveIntent(intent, null,
3493                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3494                 UserHandle.USER_SYSTEM);
3495         if (resolveInfo == null ||
3496                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3497             throw new RuntimeException("There must be exactly one uninstaller; found "
3498                     + resolveInfo);
3499         }
3500         return resolveInfo.getComponentInfo().packageName;
3501     }
3502 
getIntentFilterVerifierComponentNameLPr()3503     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3504         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3505 
3506         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3507                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3508                 UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3509         ResolveInfo best = null;
3510         final int N = matches.size();
3511         for (int i = 0; i < N; i++) {
3512             final ResolveInfo cur = matches.get(i);
3513             final String packageName = cur.getComponentInfo().packageName;
3514             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3515                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3516                 continue;
3517             }
3518 
3519             if (best == null || cur.priority > best.priority) {
3520                 best = cur;
3521             }
3522         }
3523 
3524         if (best != null) {
3525             return best.getComponentInfo().getComponentName();
3526         }
3527         Slog.w(TAG, "Intent filter verifier not found");
3528         return null;
3529     }
3530 
3531     @Override
getInstantAppResolverComponent()3532     public @Nullable ComponentName getInstantAppResolverComponent() {
3533         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3534             return null;
3535         }
3536         synchronized (mPackages) {
3537             final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3538             if (instantAppResolver == null) {
3539                 return null;
3540             }
3541             return instantAppResolver.first;
3542         }
3543     }
3544 
getInstantAppResolverLPr()3545     private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3546         final String[] packageArray =
3547                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3548         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3549             if (DEBUG_EPHEMERAL) {
3550                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3551             }
3552             return null;
3553         }
3554 
3555         final int callingUid = Binder.getCallingUid();
3556         final int resolveFlags =
3557                 MATCH_DIRECT_BOOT_AWARE
3558                 | MATCH_DIRECT_BOOT_UNAWARE
3559                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3560         String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3561         final Intent resolverIntent = new Intent(actionName);
3562         List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3563                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3564         // temporarily look for the old action
3565         if (resolvers.size() == 0) {
3566             if (DEBUG_EPHEMERAL) {
3567                 Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3568             }
3569             actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3570             resolverIntent.setAction(actionName);
3571             resolvers = queryIntentServicesInternal(resolverIntent, null,
3572                     resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3573         }
3574         final int N = resolvers.size();
3575         if (N == 0) {
3576             if (DEBUG_EPHEMERAL) {
3577                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3578             }
3579             return null;
3580         }
3581 
3582         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3583         for (int i = 0; i < N; i++) {
3584             final ResolveInfo info = resolvers.get(i);
3585 
3586             if (info.serviceInfo == null) {
3587                 continue;
3588             }
3589 
3590             final String packageName = info.serviceInfo.packageName;
3591             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3592                 if (DEBUG_EPHEMERAL) {
3593                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3594                             + " pkg: " + packageName + ", info:" + info);
3595                 }
3596                 continue;
3597             }
3598 
3599             if (DEBUG_EPHEMERAL) {
3600                 Slog.v(TAG, "Ephemeral resolver found;"
3601                         + " pkg: " + packageName + ", info:" + info);
3602             }
3603             return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3604         }
3605         if (DEBUG_EPHEMERAL) {
3606             Slog.v(TAG, "Ephemeral resolver NOT found");
3607         }
3608         return null;
3609     }
3610 
getInstantAppInstallerLPr()3611     private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3612         final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3613         intent.addCategory(Intent.CATEGORY_DEFAULT);
3614         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3615 
3616         final int resolveFlags =
3617                 MATCH_DIRECT_BOOT_AWARE
3618                 | MATCH_DIRECT_BOOT_UNAWARE
3619                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3620         List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3621                 resolveFlags, UserHandle.USER_SYSTEM);
3622         // temporarily look for the old action
3623         if (matches.isEmpty()) {
3624             if (DEBUG_EPHEMERAL) {
3625                 Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3626             }
3627             intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3628             matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3629                     resolveFlags, UserHandle.USER_SYSTEM);
3630         }
3631         Iterator<ResolveInfo> iter = matches.iterator();
3632         while (iter.hasNext()) {
3633             final ResolveInfo rInfo = iter.next();
3634             final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3635             if (ps != null) {
3636                 final PermissionsState permissionsState = ps.getPermissionsState();
3637                 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3638                     continue;
3639                 }
3640             }
3641             iter.remove();
3642         }
3643         if (matches.size() == 0) {
3644             return null;
3645         } else if (matches.size() == 1) {
3646             return (ActivityInfo) matches.get(0).getComponentInfo();
3647         } else {
3648             throw new RuntimeException(
3649                     "There must be at most one ephemeral installer; found " + matches);
3650         }
3651     }
3652 
getInstantAppResolverSettingsLPr( @onNull ComponentName resolver)3653     private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3654             @NonNull ComponentName resolver) {
3655         final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3656                 .addCategory(Intent.CATEGORY_DEFAULT)
3657                 .setPackage(resolver.getPackageName());
3658         final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3659         List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3660                 UserHandle.USER_SYSTEM);
3661         // temporarily look for the old action
3662         if (matches.isEmpty()) {
3663             if (DEBUG_EPHEMERAL) {
3664                 Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3665             }
3666             intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3667             matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3668                     UserHandle.USER_SYSTEM);
3669         }
3670         if (matches.isEmpty()) {
3671             return null;
3672         }
3673         return matches.get(0).getComponentInfo().getComponentName();
3674     }
3675 
primeDomainVerificationsLPw(int userId)3676     private void primeDomainVerificationsLPw(int userId) {
3677         if (DEBUG_DOMAIN_VERIFICATION) {
3678             Slog.d(TAG, "Priming domain verifications in user " + userId);
3679         }
3680 
3681         SystemConfig systemConfig = SystemConfig.getInstance();
3682         ArraySet<String> packages = systemConfig.getLinkedApps();
3683 
3684         for (String packageName : packages) {
3685             PackageParser.Package pkg = mPackages.get(packageName);
3686             if (pkg != null) {
3687                 if (!pkg.isSystemApp()) {
3688                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3689                     continue;
3690                 }
3691 
3692                 ArraySet<String> domains = null;
3693                 for (PackageParser.Activity a : pkg.activities) {
3694                     for (ActivityIntentInfo filter : a.intents) {
3695                         if (hasValidDomains(filter)) {
3696                             if (domains == null) {
3697                                 domains = new ArraySet<String>();
3698                             }
3699                             domains.addAll(filter.getHostsList());
3700                         }
3701                     }
3702                 }
3703 
3704                 if (domains != null && domains.size() > 0) {
3705                     if (DEBUG_DOMAIN_VERIFICATION) {
3706                         Slog.v(TAG, "      + " + packageName);
3707                     }
3708                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3709                     // state w.r.t. the formal app-linkage "no verification attempted" state;
3710                     // and then 'always' in the per-user state actually used for intent resolution.
3711                     final IntentFilterVerificationInfo ivi;
3712                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3713                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3714                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3715                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3716                 } else {
3717                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3718                             + "' does not handle web links");
3719                 }
3720             } else {
3721                 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3722             }
3723         }
3724 
3725         scheduleWritePackageRestrictionsLocked(userId);
3726         scheduleWriteSettingsLocked();
3727     }
3728 
applyFactoryDefaultBrowserLPw(int userId)3729     private void applyFactoryDefaultBrowserLPw(int userId) {
3730         // The default browser app's package name is stored in a string resource,
3731         // with a product-specific overlay used for vendor customization.
3732         String browserPkg = mContext.getResources().getString(
3733                 com.android.internal.R.string.default_browser);
3734         if (!TextUtils.isEmpty(browserPkg)) {
3735             // non-empty string => required to be a known package
3736             PackageSetting ps = mSettings.mPackages.get(browserPkg);
3737             if (ps == null) {
3738                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3739                 browserPkg = null;
3740             } else {
3741                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3742             }
3743         }
3744 
3745         // Nothing valid explicitly set? Make the factory-installed browser the explicit
3746         // default.  If there's more than one, just leave everything alone.
3747         if (browserPkg == null) {
3748             calculateDefaultBrowserLPw(userId);
3749         }
3750     }
3751 
calculateDefaultBrowserLPw(int userId)3752     private void calculateDefaultBrowserLPw(int userId) {
3753         List<String> allBrowsers = resolveAllBrowserApps(userId);
3754         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3755         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3756     }
3757 
resolveAllBrowserApps(int userId)3758     private List<String> resolveAllBrowserApps(int userId) {
3759         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3760         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3761                 PackageManager.MATCH_ALL, userId);
3762 
3763         final int count = list.size();
3764         List<String> result = new ArrayList<String>(count);
3765         for (int i=0; i<count; i++) {
3766             ResolveInfo info = list.get(i);
3767             if (info.activityInfo == null
3768                     || !info.handleAllWebDataURI
3769                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3770                     || result.contains(info.activityInfo.packageName)) {
3771                 continue;
3772             }
3773             result.add(info.activityInfo.packageName);
3774         }
3775 
3776         return result;
3777     }
3778 
packageIsBrowser(String packageName, int userId)3779     private boolean packageIsBrowser(String packageName, int userId) {
3780         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3781                 PackageManager.MATCH_ALL, userId);
3782         final int N = list.size();
3783         for (int i = 0; i < N; i++) {
3784             ResolveInfo info = list.get(i);
3785             if (packageName.equals(info.activityInfo.packageName)) {
3786                 return true;
3787             }
3788         }
3789         return false;
3790     }
3791 
checkDefaultBrowser()3792     private void checkDefaultBrowser() {
3793         final int myUserId = UserHandle.myUserId();
3794         final String packageName = getDefaultBrowserPackageName(myUserId);
3795         if (packageName != null) {
3796             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3797             if (info == null) {
3798                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3799                 synchronized (mPackages) {
3800                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3801                 }
3802             }
3803         }
3804     }
3805 
3806     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)3807     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3808             throws RemoteException {
3809         try {
3810             return super.onTransact(code, data, reply, flags);
3811         } catch (RuntimeException e) {
3812             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3813                 Slog.wtf(TAG, "Package Manager Crash", e);
3814             }
3815             throw e;
3816         }
3817     }
3818 
appendInts(int[] cur, int[] add)3819     static int[] appendInts(int[] cur, int[] add) {
3820         if (add == null) return cur;
3821         if (cur == null) return add;
3822         final int N = add.length;
3823         for (int i=0; i<N; i++) {
3824             cur = appendInt(cur, add[i]);
3825         }
3826         return cur;
3827     }
3828 
3829     /**
3830      * Returns whether or not a full application can see an instant application.
3831      * <p>
3832      * Currently, there are three cases in which this can occur:
3833      * <ol>
3834      * <li>The calling application is a "special" process. Special processes
3835      *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3836      * <li>The calling application has the permission
3837      *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3838      * <li>The calling application is the default launcher on the
3839      *     system partition.</li>
3840      * </ol>
3841      */
canViewInstantApps(int callingUid, int userId)3842     private boolean canViewInstantApps(int callingUid, int userId) {
3843         if (callingUid < Process.FIRST_APPLICATION_UID) {
3844             return true;
3845         }
3846         if (mContext.checkCallingOrSelfPermission(
3847                 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3848             return true;
3849         }
3850         if (mContext.checkCallingOrSelfPermission(
3851                 android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3852             final ComponentName homeComponent = getDefaultHomeActivity(userId);
3853             if (homeComponent != null
3854                     && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3855                 return true;
3856             }
3857         }
3858         return false;
3859     }
3860 
generatePackageInfo(PackageSetting ps, int flags, int userId)3861     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3862         if (!sUserManager.exists(userId)) return null;
3863         if (ps == null) {
3864             return null;
3865         }
3866         PackageParser.Package p = ps.pkg;
3867         if (p == null) {
3868             return null;
3869         }
3870         final int callingUid = Binder.getCallingUid();
3871         // Filter out ephemeral app metadata:
3872         //   * The system/shell/root can see metadata for any app
3873         //   * An installed app can see metadata for 1) other installed apps
3874         //     and 2) ephemeral apps that have explicitly interacted with it
3875         //   * Ephemeral apps can only see their own data and exposed installed apps
3876         //   * Holding a signature permission allows seeing instant apps
3877         if (filterAppAccessLPr(ps, callingUid, userId)) {
3878             return null;
3879         }
3880 
3881         final PermissionsState permissionsState = ps.getPermissionsState();
3882 
3883         // Compute GIDs only if requested
3884         final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3885                 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3886         // Compute granted permissions only if package has requested permissions
3887         final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3888                 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3889         final PackageUserState state = ps.readUserState(userId);
3890 
3891         if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3892                 && ps.isSystem()) {
3893             flags |= MATCH_ANY_USER;
3894         }
3895 
3896         PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3897                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3898 
3899         if (packageInfo == null) {
3900             return null;
3901         }
3902 
3903         packageInfo.packageName = packageInfo.applicationInfo.packageName =
3904                 resolveExternalPackageNameLPr(p);
3905 
3906         return packageInfo;
3907     }
3908 
3909     @Override
checkPackageStartable(String packageName, int userId)3910     public void checkPackageStartable(String packageName, int userId) {
3911         final int callingUid = Binder.getCallingUid();
3912         if (getInstantAppPackageName(callingUid) != null) {
3913             throw new SecurityException("Instant applications don't have access to this method");
3914         }
3915         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3916         synchronized (mPackages) {
3917             final PackageSetting ps = mSettings.mPackages.get(packageName);
3918             if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3919                 throw new SecurityException("Package " + packageName + " was not found!");
3920             }
3921 
3922             if (!ps.getInstalled(userId)) {
3923                 throw new SecurityException(
3924                         "Package " + packageName + " was not installed for user " + userId + "!");
3925             }
3926 
3927             if (mSafeMode && !ps.isSystem()) {
3928                 throw new SecurityException("Package " + packageName + " not a system app!");
3929             }
3930 
3931             if (mFrozenPackages.contains(packageName)) {
3932                 throw new SecurityException("Package " + packageName + " is currently frozen!");
3933             }
3934 
3935             if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3936                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3937             }
3938         }
3939     }
3940 
3941     @Override
isPackageAvailable(String packageName, int userId)3942     public boolean isPackageAvailable(String packageName, int userId) {
3943         if (!sUserManager.exists(userId)) return false;
3944         final int callingUid = Binder.getCallingUid();
3945         enforceCrossUserPermission(callingUid, userId,
3946                 false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3947         synchronized (mPackages) {
3948             PackageParser.Package p = mPackages.get(packageName);
3949             if (p != null) {
3950                 final PackageSetting ps = (PackageSetting) p.mExtras;
3951                 if (filterAppAccessLPr(ps, callingUid, userId)) {
3952                     return false;
3953                 }
3954                 if (ps != null) {
3955                     final PackageUserState state = ps.readUserState(userId);
3956                     if (state != null) {
3957                         return PackageParser.isAvailable(state);
3958                     }
3959                 }
3960             }
3961         }
3962         return false;
3963     }
3964 
3965     @Override
getPackageInfo(String packageName, int flags, int userId)3966     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3967         return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3968                 flags, Binder.getCallingUid(), userId);
3969     }
3970 
3971     @Override
getPackageInfoVersioned(VersionedPackage versionedPackage, int flags, int userId)3972     public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3973             int flags, int userId) {
3974         return getPackageInfoInternal(versionedPackage.getPackageName(),
3975                 versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3976     }
3977 
3978     /**
3979      * Important: The provided filterCallingUid is used exclusively to filter out packages
3980      * that can be seen based on user state. It's typically the original caller uid prior
3981      * to clearing. Because it can only be provided by trusted code, it's value can be
3982      * trusted and will be used as-is; unlike userId which will be validated by this method.
3983      */
getPackageInfoInternal(String packageName, int versionCode, int flags, int filterCallingUid, int userId)3984     private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3985             int flags, int filterCallingUid, int userId) {
3986         if (!sUserManager.exists(userId)) return null;
3987         flags = updateFlagsForPackage(flags, userId, packageName);
3988         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3989                 false /* requireFullPermission */, false /* checkShell */, "get package info");
3990 
3991         // reader
3992         synchronized (mPackages) {
3993             // Normalize package name to handle renamed packages and static libs
3994             packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3995 
3996             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3997             if (matchFactoryOnly) {
3998                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3999                 if (ps != null) {
4000                     if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4001                         return null;
4002                     }
4003                     if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4004                         return null;
4005                     }
4006                     return generatePackageInfo(ps, flags, userId);
4007                 }
4008             }
4009 
4010             PackageParser.Package p = mPackages.get(packageName);
4011             if (matchFactoryOnly && p != null && !isSystemApp(p)) {
4012                 return null;
4013             }
4014             if (DEBUG_PACKAGE_INFO)
4015                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4016             if (p != null) {
4017                 final PackageSetting ps = (PackageSetting) p.mExtras;
4018                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4019                     return null;
4020                 }
4021                 if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
4022                     return null;
4023                 }
4024                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
4025             }
4026             if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4027                 final PackageSetting ps = mSettings.mPackages.get(packageName);
4028                 if (ps == null) return null;
4029                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4030                     return null;
4031                 }
4032                 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4033                     return null;
4034                 }
4035                 return generatePackageInfo(ps, flags, userId);
4036             }
4037         }
4038         return null;
4039     }
4040 
isComponentVisibleToInstantApp(@ullable ComponentName component)4041     private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4042         if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4043             return true;
4044         }
4045         if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4046             return true;
4047         }
4048         if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4049             return true;
4050         }
4051         return false;
4052     }
4053 
isComponentVisibleToInstantApp( @ullable ComponentName component, @ComponentType int type)4054     private boolean isComponentVisibleToInstantApp(
4055             @Nullable ComponentName component, @ComponentType int type) {
4056         if (type == TYPE_ACTIVITY) {
4057             final PackageParser.Activity activity = mActivities.mActivities.get(component);
4058             return activity != null
4059                     ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4060                     : false;
4061         } else if (type == TYPE_RECEIVER) {
4062             final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4063             return activity != null
4064                     ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4065                     : false;
4066         } else if (type == TYPE_SERVICE) {
4067             final PackageParser.Service service = mServices.mServices.get(component);
4068             return service != null
4069                     ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4070                     : false;
4071         } else if (type == TYPE_PROVIDER) {
4072             final PackageParser.Provider provider = mProviders.mProviders.get(component);
4073             return provider != null
4074                     ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4075                     : false;
4076         } else if (type == TYPE_UNKNOWN) {
4077             return isComponentVisibleToInstantApp(component);
4078         }
4079         return false;
4080     }
4081 
4082     /**
4083      * Returns whether or not access to the application should be filtered.
4084      * <p>
4085      * Access may be limited based upon whether the calling or target applications
4086      * are instant applications.
4087      *
4088      * @see #canAccessInstantApps(int)
4089      */
filterAppAccessLPr(@ullable PackageSetting ps, int callingUid, @Nullable ComponentName component, @ComponentType int componentType, int userId)4090     private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4091             @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4092         // if we're in an isolated process, get the real calling UID
4093         if (Process.isIsolated(callingUid)) {
4094             callingUid = mIsolatedOwners.get(callingUid);
4095         }
4096         final String instantAppPkgName = getInstantAppPackageName(callingUid);
4097         final boolean callerIsInstantApp = instantAppPkgName != null;
4098         if (ps == null) {
4099             if (callerIsInstantApp) {
4100                 // pretend the application exists, but, needs to be filtered
4101                 return true;
4102             }
4103             return false;
4104         }
4105         // if the target and caller are the same application, don't filter
4106         if (isCallerSameApp(ps.name, callingUid)) {
4107             return false;
4108         }
4109         if (callerIsInstantApp) {
4110             // request for a specific component; if it hasn't been explicitly exposed, filter
4111             if (component != null) {
4112                 return !isComponentVisibleToInstantApp(component, componentType);
4113             }
4114             // request for application; if no components have been explicitly exposed, filter
4115             return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4116         }
4117         if (ps.getInstantApp(userId)) {
4118             // caller can see all components of all instant applications, don't filter
4119             if (canViewInstantApps(callingUid, userId)) {
4120                 return false;
4121             }
4122             // request for a specific instant application component, filter
4123             if (component != null) {
4124                 return true;
4125             }
4126             // request for an instant application; if the caller hasn't been granted access, filter
4127             return !mInstantAppRegistry.isInstantAccessGranted(
4128                     userId, UserHandle.getAppId(callingUid), ps.appId);
4129         }
4130         return false;
4131     }
4132 
4133     /**
4134      * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4135      */
filterAppAccessLPr(@ullable PackageSetting ps, int callingUid, int userId)4136     private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4137         return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4138     }
4139 
filterSharedLibPackageLPr(@ullable PackageSetting ps, int uid, int userId, int flags)4140     private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4141             int flags) {
4142         // Callers can access only the libs they depend on, otherwise they need to explicitly
4143         // ask for the shared libraries given the caller is allowed to access all static libs.
4144         if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4145             // System/shell/root get to see all static libs
4146             final int appId = UserHandle.getAppId(uid);
4147             if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4148                     || appId == Process.ROOT_UID) {
4149                 return false;
4150             }
4151         }
4152 
4153         // No package means no static lib as it is always on internal storage
4154         if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4155             return false;
4156         }
4157 
4158         final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4159                 ps.pkg.staticSharedLibVersion);
4160         if (libEntry == null) {
4161             return false;
4162         }
4163 
4164         final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4165         final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4166         if (uidPackageNames == null) {
4167             return true;
4168         }
4169 
4170         for (String uidPackageName : uidPackageNames) {
4171             if (ps.name.equals(uidPackageName)) {
4172                 return false;
4173             }
4174             PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4175             if (uidPs != null) {
4176                 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4177                         libEntry.info.getName());
4178                 if (index < 0) {
4179                     continue;
4180                 }
4181                 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
4182                     return false;
4183                 }
4184             }
4185         }
4186         return true;
4187     }
4188 
4189     @Override
currentToCanonicalPackageNames(String[] names)4190     public String[] currentToCanonicalPackageNames(String[] names) {
4191         final int callingUid = Binder.getCallingUid();
4192         if (getInstantAppPackageName(callingUid) != null) {
4193             return names;
4194         }
4195         final String[] out = new String[names.length];
4196         // reader
4197         synchronized (mPackages) {
4198             final int callingUserId = UserHandle.getUserId(callingUid);
4199             final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4200             for (int i=names.length-1; i>=0; i--) {
4201                 final PackageSetting ps = mSettings.mPackages.get(names[i]);
4202                 boolean translateName = false;
4203                 if (ps != null && ps.realName != null) {
4204                     final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4205                     translateName = !targetIsInstantApp
4206                             || canViewInstantApps
4207                             || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4208                                     UserHandle.getAppId(callingUid), ps.appId);
4209                 }
4210                 out[i] = translateName ? ps.realName : names[i];
4211             }
4212         }
4213         return out;
4214     }
4215 
4216     @Override
canonicalToCurrentPackageNames(String[] names)4217     public String[] canonicalToCurrentPackageNames(String[] names) {
4218         final int callingUid = Binder.getCallingUid();
4219         if (getInstantAppPackageName(callingUid) != null) {
4220             return names;
4221         }
4222         final String[] out = new String[names.length];
4223         // reader
4224         synchronized (mPackages) {
4225             final int callingUserId = UserHandle.getUserId(callingUid);
4226             final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4227             for (int i=names.length-1; i>=0; i--) {
4228                 final String cur = mSettings.getRenamedPackageLPr(names[i]);
4229                 boolean translateName = false;
4230                 if (cur != null) {
4231                     final PackageSetting ps = mSettings.mPackages.get(names[i]);
4232                     final boolean targetIsInstantApp =
4233                             ps != null && ps.getInstantApp(callingUserId);
4234                     translateName = !targetIsInstantApp
4235                             || canViewInstantApps
4236                             || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4237                                     UserHandle.getAppId(callingUid), ps.appId);
4238                 }
4239                 out[i] = translateName ? cur : names[i];
4240             }
4241         }
4242         return out;
4243     }
4244 
4245     @Override
getPackageUid(String packageName, int flags, int userId)4246     public int getPackageUid(String packageName, int flags, int userId) {
4247         if (!sUserManager.exists(userId)) return -1;
4248         final int callingUid = Binder.getCallingUid();
4249         flags = updateFlagsForPackage(flags, userId, packageName);
4250         enforceCrossUserPermission(callingUid, userId,
4251                 false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4252 
4253         // reader
4254         synchronized (mPackages) {
4255             final PackageParser.Package p = mPackages.get(packageName);
4256             if (p != null && p.isMatch(flags)) {
4257                 PackageSetting ps = (PackageSetting) p.mExtras;
4258                 if (filterAppAccessLPr(ps, callingUid, userId)) {
4259                     return -1;
4260                 }
4261                 return UserHandle.getUid(userId, p.applicationInfo.uid);
4262             }
4263             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4264                 final PackageSetting ps = mSettings.mPackages.get(packageName);
4265                 if (ps != null && ps.isMatch(flags)
4266                         && !filterAppAccessLPr(ps, callingUid, userId)) {
4267                     return UserHandle.getUid(userId, ps.appId);
4268                 }
4269             }
4270         }
4271 
4272         return -1;
4273     }
4274 
4275     @Override
getPackageGids(String packageName, int flags, int userId)4276     public int[] getPackageGids(String packageName, int flags, int userId) {
4277         if (!sUserManager.exists(userId)) return null;
4278         final int callingUid = Binder.getCallingUid();
4279         flags = updateFlagsForPackage(flags, userId, packageName);
4280         enforceCrossUserPermission(callingUid, userId,
4281                 false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4282 
4283         // reader
4284         synchronized (mPackages) {
4285             final PackageParser.Package p = mPackages.get(packageName);
4286             if (p != null && p.isMatch(flags)) {
4287                 PackageSetting ps = (PackageSetting) p.mExtras;
4288                 if (filterAppAccessLPr(ps, callingUid, userId)) {
4289                     return null;
4290                 }
4291                 // TODO: Shouldn't this be checking for package installed state for userId and
4292                 // return null?
4293                 return ps.getPermissionsState().computeGids(userId);
4294             }
4295             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4296                 final PackageSetting ps = mSettings.mPackages.get(packageName);
4297                 if (ps != null && ps.isMatch(flags)
4298                         && !filterAppAccessLPr(ps, callingUid, userId)) {
4299                     return ps.getPermissionsState().computeGids(userId);
4300                 }
4301             }
4302         }
4303 
4304         return null;
4305     }
4306 
generatePermissionInfo(BasePermission bp, int flags)4307     static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
4308         if (bp.perm != null) {
4309             return PackageParser.generatePermissionInfo(bp.perm, flags);
4310         }
4311         PermissionInfo pi = new PermissionInfo();
4312         pi.name = bp.name;
4313         pi.packageName = bp.sourcePackage;
4314         pi.nonLocalizedLabel = bp.name;
4315         pi.protectionLevel = bp.protectionLevel;
4316         return pi;
4317     }
4318 
4319     @Override
getPermissionInfo(String name, String packageName, int flags)4320     public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4321         final int callingUid = Binder.getCallingUid();
4322         if (getInstantAppPackageName(callingUid) != null) {
4323             return null;
4324         }
4325         // reader
4326         synchronized (mPackages) {
4327             final BasePermission p = mSettings.mPermissions.get(name);
4328             if (p == null) {
4329                 return null;
4330             }
4331             // If the caller is an app that targets pre 26 SDK drop protection flags.
4332             PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
4333             if (permissionInfo != null) {
4334                 final int protectionLevel = adjustPermissionProtectionFlagsLPr(
4335                         permissionInfo.protectionLevel, packageName, callingUid);
4336                 if (permissionInfo.protectionLevel != protectionLevel) {
4337                     // If we return different protection level, don't use the cached info
4338                     if (p.perm != null && p.perm.info == permissionInfo) {
4339                         permissionInfo = new PermissionInfo(permissionInfo);
4340                     }
4341                     permissionInfo.protectionLevel = protectionLevel;
4342                 }
4343             }
4344             return permissionInfo;
4345         }
4346     }
4347 
adjustPermissionProtectionFlagsLPr(int protectionLevel, String packageName, int uid)4348     private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
4349             String packageName, int uid) {
4350         // Signature permission flags area always reported
4351         final int protectionLevelMasked = protectionLevel
4352                 & (PermissionInfo.PROTECTION_NORMAL
4353                 | PermissionInfo.PROTECTION_DANGEROUS
4354                 | PermissionInfo.PROTECTION_SIGNATURE);
4355         if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
4356             return protectionLevel;
4357         }
4358 
4359         // System sees all flags.
4360         final int appId = UserHandle.getAppId(uid);
4361         if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
4362                 || appId == Process.SHELL_UID) {
4363             return protectionLevel;
4364         }
4365 
4366         // Normalize package name to handle renamed packages and static libs
4367         packageName = resolveInternalPackageNameLPr(packageName,
4368                 PackageManager.VERSION_CODE_HIGHEST);
4369 
4370         // Apps that target O see flags for all protection levels.
4371         final PackageSetting ps = mSettings.mPackages.get(packageName);
4372         if (ps == null) {
4373             return protectionLevel;
4374         }
4375         if (ps.appId != appId) {
4376             return protectionLevel;
4377         }
4378 
4379         final PackageParser.Package pkg = mPackages.get(packageName);
4380         if (pkg == null) {
4381             return protectionLevel;
4382         }
4383         if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
4384             return protectionLevelMasked;
4385         }
4386 
4387         return protectionLevel;
4388     }
4389 
4390     @Override
queryPermissionsByGroup(String group, int flags)4391     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
4392             int flags) {
4393         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4394             return null;
4395         }
4396         // reader
4397         synchronized (mPackages) {
4398             if (group != null && !mPermissionGroups.containsKey(group)) {
4399                 // This is thrown as NameNotFoundException
4400                 return null;
4401             }
4402 
4403             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4404             for (BasePermission p : mSettings.mPermissions.values()) {
4405                 if (group == null) {
4406                     if (p.perm == null || p.perm.info.group == null) {
4407                         out.add(generatePermissionInfo(p, flags));
4408                     }
4409                 } else {
4410                     if (p.perm != null && group.equals(p.perm.info.group)) {
4411                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4412                     }
4413                 }
4414             }
4415             return new ParceledListSlice<>(out);
4416         }
4417     }
4418 
4419     @Override
getPermissionGroupInfo(String name, int flags)4420     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4421         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4422             return null;
4423         }
4424         // reader
4425         synchronized (mPackages) {
4426             return PackageParser.generatePermissionGroupInfo(
4427                     mPermissionGroups.get(name), flags);
4428         }
4429     }
4430 
4431     @Override
getAllPermissionGroups(int flags)4432     public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4433         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4434             return ParceledListSlice.emptyList();
4435         }
4436         // reader
4437         synchronized (mPackages) {
4438             final int N = mPermissionGroups.size();
4439             ArrayList<PermissionGroupInfo> out
4440                     = new ArrayList<PermissionGroupInfo>(N);
4441             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4442                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4443             }
4444             return new ParceledListSlice<>(out);
4445         }
4446     }
4447 
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int filterCallingUid, int userId)4448     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4449             int filterCallingUid, int userId) {
4450         if (!sUserManager.exists(userId)) return null;
4451         PackageSetting ps = mSettings.mPackages.get(packageName);
4452         if (ps != null) {
4453             if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4454                 return null;
4455             }
4456             if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4457                 return null;
4458             }
4459             if (ps.pkg == null) {
4460                 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4461                 if (pInfo != null) {
4462                     return pInfo.applicationInfo;
4463                 }
4464                 return null;
4465             }
4466             ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4467                     ps.readUserState(userId), userId);
4468             if (ai != null) {
4469                 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4470             }
4471             return ai;
4472         }
4473         return null;
4474     }
4475 
4476     @Override
getApplicationInfo(String packageName, int flags, int userId)4477     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4478         return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4479     }
4480 
4481     /**
4482      * Important: The provided filterCallingUid is used exclusively to filter out applications
4483      * that can be seen based on user state. It's typically the original caller uid prior
4484      * to clearing. Because it can only be provided by trusted code, it's value can be
4485      * trusted and will be used as-is; unlike userId which will be validated by this method.
4486      */
getApplicationInfoInternal(String packageName, int flags, int filterCallingUid, int userId)4487     private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4488             int filterCallingUid, int userId) {
4489         if (!sUserManager.exists(userId)) return null;
4490         flags = updateFlagsForApplication(flags, userId, packageName);
4491         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4492                 false /* requireFullPermission */, false /* checkShell */, "get application info");
4493 
4494         // writer
4495         synchronized (mPackages) {
4496             // Normalize package name to handle renamed packages and static libs
4497             packageName = resolveInternalPackageNameLPr(packageName,
4498                     PackageManager.VERSION_CODE_HIGHEST);
4499 
4500             PackageParser.Package p = mPackages.get(packageName);
4501             if (DEBUG_PACKAGE_INFO) Log.v(
4502                     TAG, "getApplicationInfo " + packageName
4503                     + ": " + p);
4504             if (p != null) {
4505                 PackageSetting ps = mSettings.mPackages.get(packageName);
4506                 if (ps == null) return null;
4507                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4508                     return null;
4509                 }
4510                 if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4511                     return null;
4512                 }
4513                 // Note: isEnabledLP() does not apply here - always return info
4514                 ApplicationInfo ai = PackageParser.generateApplicationInfo(
4515                         p, flags, ps.readUserState(userId), userId);
4516                 if (ai != null) {
4517                     ai.packageName = resolveExternalPackageNameLPr(p);
4518                 }
4519                 return ai;
4520             }
4521             if ("android".equals(packageName)||"system".equals(packageName)) {
4522                 return mAndroidApplication;
4523             }
4524             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4525                 // Already generates the external package name
4526                 return generateApplicationInfoFromSettingsLPw(packageName,
4527                         flags, filterCallingUid, userId);
4528             }
4529         }
4530         return null;
4531     }
4532 
normalizePackageNameLPr(String packageName)4533     private String normalizePackageNameLPr(String packageName) {
4534         String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4535         return normalizedPackageName != null ? normalizedPackageName : packageName;
4536     }
4537 
4538     @Override
deletePreloadsFileCache()4539     public void deletePreloadsFileCache() {
4540         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4541             throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4542         }
4543         File dir = Environment.getDataPreloadsFileCacheDirectory();
4544         Slog.i(TAG, "Deleting preloaded file cache " + dir);
4545         FileUtils.deleteContents(dir);
4546     }
4547 
4548     @Override
freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, final int storageFlags, final IPackageDataObserver observer)4549     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4550             final int storageFlags, final IPackageDataObserver observer) {
4551         mContext.enforceCallingOrSelfPermission(
4552                 android.Manifest.permission.CLEAR_APP_CACHE, null);
4553         mHandler.post(() -> {
4554             boolean success = false;
4555             try {
4556                 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4557                 success = true;
4558             } catch (IOException e) {
4559                 Slog.w(TAG, e);
4560             }
4561             if (observer != null) {
4562                 try {
4563                     observer.onRemoveCompleted(null, success);
4564                 } catch (RemoteException e) {
4565                     Slog.w(TAG, e);
4566                 }
4567             }
4568         });
4569     }
4570 
4571     @Override
freeStorage(final String volumeUuid, final long freeStorageSize, final int storageFlags, final IntentSender pi)4572     public void freeStorage(final String volumeUuid, final long freeStorageSize,
4573             final int storageFlags, final IntentSender pi) {
4574         mContext.enforceCallingOrSelfPermission(
4575                 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4576         mHandler.post(() -> {
4577             boolean success = false;
4578             try {
4579                 freeStorage(volumeUuid, freeStorageSize, storageFlags);
4580                 success = true;
4581             } catch (IOException e) {
4582                 Slog.w(TAG, e);
4583             }
4584             if (pi != null) {
4585                 try {
4586                     pi.sendIntent(null, success ? 1 : 0, null, null, null);
4587                 } catch (SendIntentException e) {
4588                     Slog.w(TAG, e);
4589                 }
4590             }
4591         });
4592     }
4593 
4594     /**
4595      * Blocking call to clear various types of cached data across the system
4596      * until the requested bytes are available.
4597      */
freeStorage(String volumeUuid, long bytes, int storageFlags)4598     public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4599         final StorageManager storage = mContext.getSystemService(StorageManager.class);
4600         final File file = storage.findPathForUuid(volumeUuid);
4601         if (file.getUsableSpace() >= bytes) return;
4602 
4603         if (ENABLE_FREE_CACHE_V2) {
4604             final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4605                     volumeUuid);
4606             final boolean aggressive = (storageFlags
4607                     & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4608             final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4609 
4610             // 1. Pre-flight to determine if we have any chance to succeed
4611             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4612             if (internalVolume && (aggressive || SystemProperties
4613                     .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4614                 deletePreloadsFileCache();
4615                 if (file.getUsableSpace() >= bytes) return;
4616             }
4617 
4618             // 3. Consider parsed APK data (aggressive only)
4619             if (internalVolume && aggressive) {
4620                 FileUtils.deleteContents(mCacheDir);
4621                 if (file.getUsableSpace() >= bytes) return;
4622             }
4623 
4624             // 4. Consider cached app data (above quotas)
4625             try {
4626                 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4627                         Installer.FLAG_FREE_CACHE_V2);
4628             } catch (InstallerException ignored) {
4629             }
4630             if (file.getUsableSpace() >= bytes) return;
4631 
4632             // 5. Consider shared libraries with refcount=0 and age>min cache period
4633             if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4634                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4635                             Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4636                             DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4637                 return;
4638             }
4639 
4640             // 6. Consider dexopt output (aggressive only)
4641             // TODO: Implement
4642 
4643             // 7. Consider installed instant apps unused longer than min cache period
4644             if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4645                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4646                             Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4647                             InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4648                 return;
4649             }
4650 
4651             // 8. Consider cached app data (below quotas)
4652             try {
4653                 mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4654                         Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4655             } catch (InstallerException ignored) {
4656             }
4657             if (file.getUsableSpace() >= bytes) return;
4658 
4659             // 9. Consider DropBox entries
4660             // TODO: Implement
4661 
4662             // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4663             if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4664                     android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4665                             Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4666                             InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4667                 return;
4668             }
4669         } else {
4670             try {
4671                 mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4672             } catch (InstallerException ignored) {
4673             }
4674             if (file.getUsableSpace() >= bytes) return;
4675         }
4676 
4677         throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4678     }
4679 
pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)4680     private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4681             throws IOException {
4682         final StorageManager storage = mContext.getSystemService(StorageManager.class);
4683         final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4684 
4685         List<VersionedPackage> packagesToDelete = null;
4686         final long now = System.currentTimeMillis();
4687 
4688         synchronized (mPackages) {
4689             final int[] allUsers = sUserManager.getUserIds();
4690             final int libCount = mSharedLibraries.size();
4691             for (int i = 0; i < libCount; i++) {
4692                 final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4693                 if (versionedLib == null) {
4694                     continue;
4695                 }
4696                 final int versionCount = versionedLib.size();
4697                 for (int j = 0; j < versionCount; j++) {
4698                     SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4699                     // Skip packages that are not static shared libs.
4700                     if (!libInfo.isStatic()) {
4701                         break;
4702                     }
4703                     // Important: We skip static shared libs used for some user since
4704                     // in such a case we need to keep the APK on the device. The check for
4705                     // a lib being used for any user is performed by the uninstall call.
4706                     final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4707                     // Resolve the package name - we use synthetic package names internally
4708                     final String internalPackageName = resolveInternalPackageNameLPr(
4709                             declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4710                     final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4711                     // Skip unused static shared libs cached less than the min period
4712                     // to prevent pruning a lib needed by a subsequently installed package.
4713                     if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4714                         continue;
4715                     }
4716                     if (packagesToDelete == null) {
4717                         packagesToDelete = new ArrayList<>();
4718                     }
4719                     packagesToDelete.add(new VersionedPackage(internalPackageName,
4720                             declaringPackage.getVersionCode()));
4721                 }
4722             }
4723         }
4724 
4725         if (packagesToDelete != null) {
4726             final int packageCount = packagesToDelete.size();
4727             for (int i = 0; i < packageCount; i++) {
4728                 final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4729                 // Delete the package synchronously (will fail of the lib used for any user).
4730                 if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4731                         UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4732                                 == PackageManager.DELETE_SUCCEEDED) {
4733                     if (volume.getUsableSpace() >= neededSpace) {
4734                         return true;
4735                     }
4736                 }
4737             }
4738         }
4739 
4740         return false;
4741     }
4742 
4743     /**
4744      * Update given flags based on encryption status of current user.
4745      */
updateFlags(int flags, int userId)4746     private int updateFlags(int flags, int userId) {
4747         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4748                 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4749             // Caller expressed an explicit opinion about what encryption
4750             // aware/unaware components they want to see, so fall through and
4751             // give them what they want
4752         } else {
4753             // Caller expressed no opinion, so match based on user state
4754             if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4755                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4756             } else {
4757                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4758             }
4759         }
4760         return flags;
4761     }
4762 
getUserManagerInternal()4763     private UserManagerInternal getUserManagerInternal() {
4764         if (mUserManagerInternal == null) {
4765             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4766         }
4767         return mUserManagerInternal;
4768     }
4769 
getDeviceIdleController()4770     private DeviceIdleController.LocalService getDeviceIdleController() {
4771         if (mDeviceIdleController == null) {
4772             mDeviceIdleController =
4773                     LocalServices.getService(DeviceIdleController.LocalService.class);
4774         }
4775         return mDeviceIdleController;
4776     }
4777 
4778     /**
4779      * Update given flags when being used to request {@link PackageInfo}.
4780      */
updateFlagsForPackage(int flags, int userId, Object cookie)4781     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4782         final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4783         boolean triaged = true;
4784         if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4785                 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4786             // Caller is asking for component details, so they'd better be
4787             // asking for specific encryption matching behavior, or be triaged
4788             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4789                     | PackageManager.MATCH_DIRECT_BOOT_AWARE
4790                     | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4791                 triaged = false;
4792             }
4793         }
4794         if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4795                 | PackageManager.MATCH_SYSTEM_ONLY
4796                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4797             triaged = false;
4798         }
4799         if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4800             enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4801                     "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4802                     + Debug.getCallers(5));
4803         } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4804                 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4805             // If the caller wants all packages and has a restricted profile associated with it,
4806             // then match all users. This is to make sure that launchers that need to access work
4807             // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4808             // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4809             flags |= PackageManager.MATCH_ANY_USER;
4810         }
4811         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4812             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4813                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4814         }
4815         return updateFlags(flags, userId);
4816     }
4817 
4818     /**
4819      * Update given flags when being used to request {@link ApplicationInfo}.
4820      */
updateFlagsForApplication(int flags, int userId, Object cookie)4821     private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4822         return updateFlagsForPackage(flags, userId, cookie);
4823     }
4824 
4825     /**
4826      * Update given flags when being used to request {@link ComponentInfo}.
4827      */
updateFlagsForComponent(int flags, int userId, Object cookie)4828     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4829         if (cookie instanceof Intent) {
4830             if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4831                 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4832             }
4833         }
4834 
4835         boolean triaged = true;
4836         // Caller is asking for component details, so they'd better be
4837         // asking for specific encryption matching behavior, or be triaged
4838         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4839                 | PackageManager.MATCH_DIRECT_BOOT_AWARE
4840                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4841             triaged = false;
4842         }
4843         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4844             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4845                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4846         }
4847 
4848         return updateFlags(flags, userId);
4849     }
4850 
4851     /**
4852      * Update given intent when being used to request {@link ResolveInfo}.
4853      */
updateIntentForResolve(Intent intent)4854     private Intent updateIntentForResolve(Intent intent) {
4855         if (intent.getSelector() != null) {
4856             intent = intent.getSelector();
4857         }
4858         if (DEBUG_PREFERRED) {
4859             intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4860         }
4861         return intent;
4862     }
4863 
4864     /**
4865      * Update given flags when being used to request {@link ResolveInfo}.
4866      * <p>Instant apps are resolved specially, depending upon context. Minimally,
4867      * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4868      * flag set. However, this flag is only honoured in three circumstances:
4869      * <ul>
4870      * <li>when called from a system process</li>
4871      * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4872      * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4873      * action and a {@code android.intent.category.BROWSABLE} category</li>
4874      * </ul>
4875      */
updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid)4876     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4877         return updateFlagsForResolve(flags, userId, intent, callingUid,
4878                 false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4879     }
updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid, boolean wantInstantApps)4880     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4881             boolean wantInstantApps) {
4882         return updateFlagsForResolve(flags, userId, intent, callingUid,
4883                 wantInstantApps, false /*onlyExposedExplicitly*/);
4884     }
updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid, boolean wantInstantApps, boolean onlyExposedExplicitly)4885     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4886             boolean wantInstantApps, boolean onlyExposedExplicitly) {
4887         // Safe mode means we shouldn't match any third-party components
4888         if (mSafeMode) {
4889             flags |= PackageManager.MATCH_SYSTEM_ONLY;
4890         }
4891         if (getInstantAppPackageName(callingUid) != null) {
4892             // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4893             if (onlyExposedExplicitly) {
4894                 flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4895             }
4896             flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4897             flags |= PackageManager.MATCH_INSTANT;
4898         } else {
4899             final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4900             final boolean allowMatchInstant =
4901                     (wantInstantApps
4902                             && Intent.ACTION_VIEW.equals(intent.getAction())
4903                             && hasWebURI(intent))
4904                     || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4905             flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4906                     | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4907             if (!allowMatchInstant) {
4908                 flags &= ~PackageManager.MATCH_INSTANT;
4909             }
4910         }
4911         return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4912     }
4913 
4914     @Override
getActivityInfo(ComponentName component, int flags, int userId)4915     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4916         return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4917     }
4918 
4919     /**
4920      * Important: The provided filterCallingUid is used exclusively to filter out activities
4921      * that can be seen based on user state. It's typically the original caller uid prior
4922      * to clearing. Because it can only be provided by trusted code, it's value can be
4923      * trusted and will be used as-is; unlike userId which will be validated by this method.
4924      */
getActivityInfoInternal(ComponentName component, int flags, int filterCallingUid, int userId)4925     private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4926             int filterCallingUid, int userId) {
4927         if (!sUserManager.exists(userId)) return null;
4928         flags = updateFlagsForComponent(flags, userId, component);
4929         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4930                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
4931         synchronized (mPackages) {
4932             PackageParser.Activity a = mActivities.mActivities.get(component);
4933 
4934             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4935             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4936                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4937                 if (ps == null) return null;
4938                 if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4939                     return null;
4940                 }
4941                 return PackageParser.generateActivityInfo(
4942                         a, flags, ps.readUserState(userId), userId);
4943             }
4944             if (mResolveComponentName.equals(component)) {
4945                 return PackageParser.generateActivityInfo(
4946                         mResolveActivity, flags, new PackageUserState(), userId);
4947             }
4948         }
4949         return null;
4950     }
4951 
4952     @Override
activitySupportsIntent(ComponentName component, Intent intent, String resolvedType)4953     public boolean activitySupportsIntent(ComponentName component, Intent intent,
4954             String resolvedType) {
4955         synchronized (mPackages) {
4956             if (component.equals(mResolveComponentName)) {
4957                 // The resolver supports EVERYTHING!
4958                 return true;
4959             }
4960             final int callingUid = Binder.getCallingUid();
4961             final int callingUserId = UserHandle.getUserId(callingUid);
4962             PackageParser.Activity a = mActivities.mActivities.get(component);
4963             if (a == null) {
4964                 return false;
4965             }
4966             PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4967             if (ps == null) {
4968                 return false;
4969             }
4970             if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4971                 return false;
4972             }
4973             for (int i=0; i<a.intents.size(); i++) {
4974                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4975                         intent.getData(), intent.getCategories(), TAG) >= 0) {
4976                     return true;
4977                 }
4978             }
4979             return false;
4980         }
4981     }
4982 
4983     @Override
getReceiverInfo(ComponentName component, int flags, int userId)4984     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4985         if (!sUserManager.exists(userId)) return null;
4986         final int callingUid = Binder.getCallingUid();
4987         flags = updateFlagsForComponent(flags, userId, component);
4988         enforceCrossUserPermission(callingUid, userId,
4989                 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4990         synchronized (mPackages) {
4991             PackageParser.Activity a = mReceivers.mActivities.get(component);
4992             if (DEBUG_PACKAGE_INFO) Log.v(
4993                 TAG, "getReceiverInfo " + component + ": " + a);
4994             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4995                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4996                 if (ps == null) return null;
4997                 if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4998                     return null;
4999                 }
5000                 return PackageParser.generateActivityInfo(
5001                         a, flags, ps.readUserState(userId), userId);
5002             }
5003         }
5004         return null;
5005     }
5006 
5007     @Override
getSharedLibraries(String packageName, int flags, int userId)5008     public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
5009             int flags, int userId) {
5010         if (!sUserManager.exists(userId)) return null;
5011         Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5012         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5013             return null;
5014         }
5015 
5016         flags = updateFlagsForPackage(flags, userId, null);
5017 
5018         final boolean canSeeStaticLibraries =
5019                 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
5020                         == PERMISSION_GRANTED
5021                 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
5022                         == PERMISSION_GRANTED
5023                 || canRequestPackageInstallsInternal(packageName,
5024                         PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
5025                         false  /* throwIfPermNotDeclared*/)
5026                 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
5027                         == PERMISSION_GRANTED;
5028 
5029         synchronized (mPackages) {
5030             List<SharedLibraryInfo> result = null;
5031 
5032             final int libCount = mSharedLibraries.size();
5033             for (int i = 0; i < libCount; i++) {
5034                 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5035                 if (versionedLib == null) {
5036                     continue;
5037                 }
5038 
5039                 final int versionCount = versionedLib.size();
5040                 for (int j = 0; j < versionCount; j++) {
5041                     SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
5042                     if (!canSeeStaticLibraries && libInfo.isStatic()) {
5043                         break;
5044                     }
5045                     final long identity = Binder.clearCallingIdentity();
5046                     try {
5047                         PackageInfo packageInfo = getPackageInfoVersioned(
5048                                 libInfo.getDeclaringPackage(), flags
5049                                         | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5050                         if (packageInfo == null) {
5051                             continue;
5052                         }
5053                     } finally {
5054                         Binder.restoreCallingIdentity(identity);
5055                     }
5056 
5057                     SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
5058                             libInfo.getVersion(), libInfo.getType(),
5059                             libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
5060                             flags, userId));
5061 
5062                     if (result == null) {
5063                         result = new ArrayList<>();
5064                     }
5065                     result.add(resLibInfo);
5066                 }
5067             }
5068 
5069             return result != null ? new ParceledListSlice<>(result) : null;
5070         }
5071     }
5072 
getPackagesUsingSharedLibraryLPr( SharedLibraryInfo libInfo, int flags, int userId)5073     private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5074             SharedLibraryInfo libInfo, int flags, int userId) {
5075         List<VersionedPackage> versionedPackages = null;
5076         final int packageCount = mSettings.mPackages.size();
5077         for (int i = 0; i < packageCount; i++) {
5078             PackageSetting ps = mSettings.mPackages.valueAt(i);
5079 
5080             if (ps == null) {
5081                 continue;
5082             }
5083 
5084             if (!ps.getUserState().get(userId).isAvailable(flags)) {
5085                 continue;
5086             }
5087 
5088             final String libName = libInfo.getName();
5089             if (libInfo.isStatic()) {
5090                 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5091                 if (libIdx < 0) {
5092                     continue;
5093                 }
5094                 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
5095                     continue;
5096                 }
5097                 if (versionedPackages == null) {
5098                     versionedPackages = new ArrayList<>();
5099                 }
5100                 // If the dependent is a static shared lib, use the public package name
5101                 String dependentPackageName = ps.name;
5102                 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5103                     dependentPackageName = ps.pkg.manifestPackageName;
5104                 }
5105                 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5106             } else if (ps.pkg != null) {
5107                 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5108                         || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5109                     if (versionedPackages == null) {
5110                         versionedPackages = new ArrayList<>();
5111                     }
5112                     versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5113                 }
5114             }
5115         }
5116 
5117         return versionedPackages;
5118     }
5119 
5120     @Override
getServiceInfo(ComponentName component, int flags, int userId)5121     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5122         if (!sUserManager.exists(userId)) return null;
5123         final int callingUid = Binder.getCallingUid();
5124         flags = updateFlagsForComponent(flags, userId, component);
5125         enforceCrossUserPermission(callingUid, userId,
5126                 false /* requireFullPermission */, false /* checkShell */, "get service info");
5127         synchronized (mPackages) {
5128             PackageParser.Service s = mServices.mServices.get(component);
5129             if (DEBUG_PACKAGE_INFO) Log.v(
5130                 TAG, "getServiceInfo " + component + ": " + s);
5131             if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5132                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5133                 if (ps == null) return null;
5134                 if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5135                     return null;
5136                 }
5137                 return PackageParser.generateServiceInfo(
5138                         s, flags, ps.readUserState(userId), userId);
5139             }
5140         }
5141         return null;
5142     }
5143 
5144     @Override
getProviderInfo(ComponentName component, int flags, int userId)5145     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5146         if (!sUserManager.exists(userId)) return null;
5147         final int callingUid = Binder.getCallingUid();
5148         flags = updateFlagsForComponent(flags, userId, component);
5149         enforceCrossUserPermission(callingUid, userId,
5150                 false /* requireFullPermission */, false /* checkShell */, "get provider info");
5151         synchronized (mPackages) {
5152             PackageParser.Provider p = mProviders.mProviders.get(component);
5153             if (DEBUG_PACKAGE_INFO) Log.v(
5154                 TAG, "getProviderInfo " + component + ": " + p);
5155             if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5156                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5157                 if (ps == null) return null;
5158                 if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5159                     return null;
5160                 }
5161                 return PackageParser.generateProviderInfo(
5162                         p, flags, ps.readUserState(userId), userId);
5163             }
5164         }
5165         return null;
5166     }
5167 
5168     @Override
getSystemSharedLibraryNames()5169     public String[] getSystemSharedLibraryNames() {
5170         // allow instant applications
5171         synchronized (mPackages) {
5172             Set<String> libs = null;
5173             final int libCount = mSharedLibraries.size();
5174             for (int i = 0; i < libCount; i++) {
5175                 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5176                 if (versionedLib == null) {
5177                     continue;
5178                 }
5179                 final int versionCount = versionedLib.size();
5180                 for (int j = 0; j < versionCount; j++) {
5181                     SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5182                     if (!libEntry.info.isStatic()) {
5183                         if (libs == null) {
5184                             libs = new ArraySet<>();
5185                         }
5186                         libs.add(libEntry.info.getName());
5187                         break;
5188                     }
5189                     PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5190                     if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5191                             UserHandle.getUserId(Binder.getCallingUid()),
5192                             PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5193                         if (libs == null) {
5194                             libs = new ArraySet<>();
5195                         }
5196                         libs.add(libEntry.info.getName());
5197                         break;
5198                     }
5199                 }
5200             }
5201 
5202             if (libs != null) {
5203                 String[] libsArray = new String[libs.size()];
5204                 libs.toArray(libsArray);
5205                 return libsArray;
5206             }
5207 
5208             return null;
5209         }
5210     }
5211 
5212     @Override
getServicesSystemSharedLibraryPackageName()5213     public @NonNull String getServicesSystemSharedLibraryPackageName() {
5214         // allow instant applications
5215         synchronized (mPackages) {
5216             return mServicesSystemSharedLibraryPackageName;
5217         }
5218     }
5219 
5220     @Override
getSharedSystemSharedLibraryPackageName()5221     public @NonNull String getSharedSystemSharedLibraryPackageName() {
5222         // allow instant applications
5223         synchronized (mPackages) {
5224             return mSharedSystemSharedLibraryPackageName;
5225         }
5226     }
5227 
updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList)5228     private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5229         for (int i = userList.length - 1; i >= 0; --i) {
5230             final int userId = userList[i];
5231             // don't add instant app to the list of updates
5232             if (pkgSetting.getInstantApp(userId)) {
5233                 continue;
5234             }
5235             SparseArray<String> changedPackages = mChangedPackages.get(userId);
5236             if (changedPackages == null) {
5237                 changedPackages = new SparseArray<>();
5238                 mChangedPackages.put(userId, changedPackages);
5239             }
5240             Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5241             if (sequenceNumbers == null) {
5242                 sequenceNumbers = new HashMap<>();
5243                 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5244             }
5245             final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5246             if (sequenceNumber != null) {
5247                 changedPackages.remove(sequenceNumber);
5248             }
5249             changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5250             sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5251         }
5252         mChangedPackagesSequenceNumber++;
5253     }
5254 
5255     @Override
getChangedPackages(int sequenceNumber, int userId)5256     public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5257         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5258             return null;
5259         }
5260         synchronized (mPackages) {
5261             if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5262                 return null;
5263             }
5264             final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5265             if (changedPackages == null) {
5266                 return null;
5267             }
5268             final List<String> packageNames =
5269                     new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5270             for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5271                 final String packageName = changedPackages.get(i);
5272                 if (packageName != null) {
5273                     packageNames.add(packageName);
5274                 }
5275             }
5276             return packageNames.isEmpty()
5277                     ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5278         }
5279     }
5280 
5281     @Override
getSystemAvailableFeatures()5282     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5283         // allow instant applications
5284         ArrayList<FeatureInfo> res;
5285         synchronized (mAvailableFeatures) {
5286             res = new ArrayList<>(mAvailableFeatures.size() + 1);
5287             res.addAll(mAvailableFeatures.values());
5288         }
5289         final FeatureInfo fi = new FeatureInfo();
5290         fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5291                 FeatureInfo.GL_ES_VERSION_UNDEFINED);
5292         res.add(fi);
5293 
5294         return new ParceledListSlice<>(res);
5295     }
5296 
5297     @Override
hasSystemFeature(String name, int version)5298     public boolean hasSystemFeature(String name, int version) {
5299         // allow instant applications
5300         synchronized (mAvailableFeatures) {
5301             final FeatureInfo feat = mAvailableFeatures.get(name);
5302             if (feat == null) {
5303                 return false;
5304             } else {
5305                 return feat.version >= version;
5306             }
5307         }
5308     }
5309 
5310     @Override
checkPermission(String permName, String pkgName, int userId)5311     public int checkPermission(String permName, String pkgName, int userId) {
5312         if (!sUserManager.exists(userId)) {
5313             return PackageManager.PERMISSION_DENIED;
5314         }
5315         final int callingUid = Binder.getCallingUid();
5316 
5317         synchronized (mPackages) {
5318             final PackageParser.Package p = mPackages.get(pkgName);
5319             if (p != null && p.mExtras != null) {
5320                 final PackageSetting ps = (PackageSetting) p.mExtras;
5321                 if (filterAppAccessLPr(ps, callingUid, userId)) {
5322                     return PackageManager.PERMISSION_DENIED;
5323                 }
5324                 final boolean instantApp = ps.getInstantApp(userId);
5325                 final PermissionsState permissionsState = ps.getPermissionsState();
5326                 if (permissionsState.hasPermission(permName, userId)) {
5327                     if (instantApp) {
5328                         BasePermission bp = mSettings.mPermissions.get(permName);
5329                         if (bp != null && bp.isInstant()) {
5330                             return PackageManager.PERMISSION_GRANTED;
5331                         }
5332                     } else {
5333                         return PackageManager.PERMISSION_GRANTED;
5334                     }
5335                 }
5336                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5337                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5338                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5339                     return PackageManager.PERMISSION_GRANTED;
5340                 }
5341             }
5342         }
5343 
5344         return PackageManager.PERMISSION_DENIED;
5345     }
5346 
5347     @Override
checkUidPermission(String permName, int uid)5348     public int checkUidPermission(String permName, int uid) {
5349         final int callingUid = Binder.getCallingUid();
5350         final int callingUserId = UserHandle.getUserId(callingUid);
5351         final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5352         final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5353         final int userId = UserHandle.getUserId(uid);
5354         if (!sUserManager.exists(userId)) {
5355             return PackageManager.PERMISSION_DENIED;
5356         }
5357 
5358         synchronized (mPackages) {
5359             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5360             if (obj != null) {
5361                 if (obj instanceof SharedUserSetting) {
5362                     if (isCallerInstantApp) {
5363                         return PackageManager.PERMISSION_DENIED;
5364                     }
5365                 } else if (obj instanceof PackageSetting) {
5366                     final PackageSetting ps = (PackageSetting) obj;
5367                     if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5368                         return PackageManager.PERMISSION_DENIED;
5369                     }
5370                 }
5371                 final SettingBase settingBase = (SettingBase) obj;
5372                 final PermissionsState permissionsState = settingBase.getPermissionsState();
5373                 if (permissionsState.hasPermission(permName, userId)) {
5374                     if (isUidInstantApp) {
5375                         BasePermission bp = mSettings.mPermissions.get(permName);
5376                         if (bp != null && bp.isInstant()) {
5377                             return PackageManager.PERMISSION_GRANTED;
5378                         }
5379                     } else {
5380                         return PackageManager.PERMISSION_GRANTED;
5381                     }
5382                 }
5383                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5384                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5385                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5386                     return PackageManager.PERMISSION_GRANTED;
5387                 }
5388             } else {
5389                 ArraySet<String> perms = mSystemPermissions.get(uid);
5390                 if (perms != null) {
5391                     if (perms.contains(permName)) {
5392                         return PackageManager.PERMISSION_GRANTED;
5393                     }
5394                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5395                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5396                         return PackageManager.PERMISSION_GRANTED;
5397                     }
5398                 }
5399             }
5400         }
5401 
5402         return PackageManager.PERMISSION_DENIED;
5403     }
5404 
5405     @Override
isPermissionRevokedByPolicy(String permission, String packageName, int userId)5406     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5407         if (UserHandle.getCallingUserId() != userId) {
5408             mContext.enforceCallingPermission(
5409                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5410                     "isPermissionRevokedByPolicy for user " + userId);
5411         }
5412 
5413         if (checkPermission(permission, packageName, userId)
5414                 == PackageManager.PERMISSION_GRANTED) {
5415             return false;
5416         }
5417 
5418         final int callingUid = Binder.getCallingUid();
5419         if (getInstantAppPackageName(callingUid) != null) {
5420             if (!isCallerSameApp(packageName, callingUid)) {
5421                 return false;
5422             }
5423         } else {
5424             if (isInstantApp(packageName, userId)) {
5425                 return false;
5426             }
5427         }
5428 
5429         final long identity = Binder.clearCallingIdentity();
5430         try {
5431             final int flags = getPermissionFlags(permission, packageName, userId);
5432             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5433         } finally {
5434             Binder.restoreCallingIdentity(identity);
5435         }
5436     }
5437 
5438     @Override
getPermissionControllerPackageName()5439     public String getPermissionControllerPackageName() {
5440         synchronized (mPackages) {
5441             return mRequiredInstallerPackage;
5442         }
5443     }
5444 
5445     /**
5446      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5447      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5448      * @param checkShell whether to prevent shell from access if there's a debugging restriction
5449      * @param message the message to log on security exception
5450      */
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message)5451     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5452             boolean checkShell, String message) {
5453         if (userId < 0) {
5454             throw new IllegalArgumentException("Invalid userId " + userId);
5455         }
5456         if (checkShell) {
5457             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5458         }
5459         if (userId == UserHandle.getUserId(callingUid)) return;
5460         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5461             if (requireFullPermission) {
5462                 mContext.enforceCallingOrSelfPermission(
5463                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5464             } else {
5465                 try {
5466                     mContext.enforceCallingOrSelfPermission(
5467                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5468                 } catch (SecurityException se) {
5469                     mContext.enforceCallingOrSelfPermission(
5470                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5471                 }
5472             }
5473         }
5474     }
5475 
enforceShellRestriction(String restriction, int callingUid, int userHandle)5476     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5477         if (callingUid == Process.SHELL_UID) {
5478             if (userHandle >= 0
5479                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
5480                 throw new SecurityException("Shell does not have permission to access user "
5481                         + userHandle);
5482             } else if (userHandle < 0) {
5483                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5484                         + Debug.getCallers(3));
5485             }
5486         }
5487     }
5488 
findPermissionTreeLP(String permName)5489     private BasePermission findPermissionTreeLP(String permName) {
5490         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5491             if (permName.startsWith(bp.name) &&
5492                     permName.length() > bp.name.length() &&
5493                     permName.charAt(bp.name.length()) == '.') {
5494                 return bp;
5495             }
5496         }
5497         return null;
5498     }
5499 
checkPermissionTreeLP(String permName)5500     private BasePermission checkPermissionTreeLP(String permName) {
5501         if (permName != null) {
5502             BasePermission bp = findPermissionTreeLP(permName);
5503             if (bp != null) {
5504                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5505                     return bp;
5506                 }
5507                 throw new SecurityException("Calling uid "
5508                         + Binder.getCallingUid()
5509                         + " is not allowed to add to permission tree "
5510                         + bp.name + " owned by uid " + bp.uid);
5511             }
5512         }
5513         throw new SecurityException("No permission tree found for " + permName);
5514     }
5515 
compareStrings(CharSequence s1, CharSequence s2)5516     static boolean compareStrings(CharSequence s1, CharSequence s2) {
5517         if (s1 == null) {
5518             return s2 == null;
5519         }
5520         if (s2 == null) {
5521             return false;
5522         }
5523         if (s1.getClass() != s2.getClass()) {
5524             return false;
5525         }
5526         return s1.equals(s2);
5527     }
5528 
comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2)5529     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5530         if (pi1.icon != pi2.icon) return false;
5531         if (pi1.logo != pi2.logo) return false;
5532         if (pi1.protectionLevel != pi2.protectionLevel) return false;
5533         if (!compareStrings(pi1.name, pi2.name)) return false;
5534         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5535         // We'll take care of setting this one.
5536         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5537         // These are not currently stored in settings.
5538         //if (!compareStrings(pi1.group, pi2.group)) return false;
5539         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5540         //if (pi1.labelRes != pi2.labelRes) return false;
5541         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5542         return true;
5543     }
5544 
permissionInfoFootprint(PermissionInfo info)5545     int permissionInfoFootprint(PermissionInfo info) {
5546         int size = info.name.length();
5547         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5548         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5549         return size;
5550     }
5551 
calculateCurrentPermissionFootprintLocked(BasePermission tree)5552     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5553         int size = 0;
5554         for (BasePermission perm : mSettings.mPermissions.values()) {
5555             if (perm.uid == tree.uid) {
5556                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5557             }
5558         }
5559         return size;
5560     }
5561 
enforcePermissionCapLocked(PermissionInfo info, BasePermission tree)5562     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5563         // We calculate the max size of permissions defined by this uid and throw
5564         // if that plus the size of 'info' would exceed our stated maximum.
5565         if (tree.uid != Process.SYSTEM_UID) {
5566             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5567             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5568                 throw new SecurityException("Permission tree size cap exceeded");
5569             }
5570         }
5571     }
5572 
addPermissionLocked(PermissionInfo info, boolean async)5573     boolean addPermissionLocked(PermissionInfo info, boolean async) {
5574         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5575             throw new SecurityException("Instant apps can't add permissions");
5576         }
5577         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5578             throw new SecurityException("Label must be specified in permission");
5579         }
5580         BasePermission tree = checkPermissionTreeLP(info.name);
5581         BasePermission bp = mSettings.mPermissions.get(info.name);
5582         boolean added = bp == null;
5583         boolean changed = true;
5584         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5585         if (added) {
5586             enforcePermissionCapLocked(info, tree);
5587             bp = new BasePermission(info.name, tree.sourcePackage,
5588                     BasePermission.TYPE_DYNAMIC);
5589         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5590             throw new SecurityException(
5591                     "Not allowed to modify non-dynamic permission "
5592                     + info.name);
5593         } else {
5594             if (bp.protectionLevel == fixedLevel
5595                     && bp.perm.owner.equals(tree.perm.owner)
5596                     && bp.uid == tree.uid
5597                     && comparePermissionInfos(bp.perm.info, info)) {
5598                 changed = false;
5599             }
5600         }
5601         bp.protectionLevel = fixedLevel;
5602         info = new PermissionInfo(info);
5603         info.protectionLevel = fixedLevel;
5604         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5605         bp.perm.info.packageName = tree.perm.info.packageName;
5606         bp.uid = tree.uid;
5607         if (added) {
5608             mSettings.mPermissions.put(info.name, bp);
5609         }
5610         if (changed) {
5611             if (!async) {
5612                 mSettings.writeLPr();
5613             } else {
5614                 scheduleWriteSettingsLocked();
5615             }
5616         }
5617         return added;
5618     }
5619 
5620     @Override
addPermission(PermissionInfo info)5621     public boolean addPermission(PermissionInfo info) {
5622         synchronized (mPackages) {
5623             return addPermissionLocked(info, false);
5624         }
5625     }
5626 
5627     @Override
addPermissionAsync(PermissionInfo info)5628     public boolean addPermissionAsync(PermissionInfo info) {
5629         synchronized (mPackages) {
5630             return addPermissionLocked(info, true);
5631         }
5632     }
5633 
5634     @Override
removePermission(String name)5635     public void removePermission(String name) {
5636         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5637             throw new SecurityException("Instant applications don't have access to this method");
5638         }
5639         synchronized (mPackages) {
5640             checkPermissionTreeLP(name);
5641             BasePermission bp = mSettings.mPermissions.get(name);
5642             if (bp != null) {
5643                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
5644                     throw new SecurityException(
5645                             "Not allowed to modify non-dynamic permission "
5646                             + name);
5647                 }
5648                 mSettings.mPermissions.remove(name);
5649                 mSettings.writeLPr();
5650             }
5651         }
5652     }
5653 
enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission( PackageParser.Package pkg, BasePermission bp)5654     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5655             PackageParser.Package pkg, BasePermission bp) {
5656         int index = pkg.requestedPermissions.indexOf(bp.name);
5657         if (index == -1) {
5658             throw new SecurityException("Package " + pkg.packageName
5659                     + " has not requested permission " + bp.name);
5660         }
5661         if (!bp.isRuntime() && !bp.isDevelopment()) {
5662             throw new SecurityException("Permission " + bp.name
5663                     + " is not a changeable permission type");
5664         }
5665     }
5666 
5667     @Override
grantRuntimePermission(String packageName, String name, final int userId)5668     public void grantRuntimePermission(String packageName, String name, final int userId) {
5669         grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5670     }
5671 
grantRuntimePermission(String packageName, String name, final int userId, boolean overridePolicy)5672     private void grantRuntimePermission(String packageName, String name, final int userId,
5673             boolean overridePolicy) {
5674         if (!sUserManager.exists(userId)) {
5675             Log.e(TAG, "No such user:" + userId);
5676             return;
5677         }
5678         final int callingUid = Binder.getCallingUid();
5679 
5680         mContext.enforceCallingOrSelfPermission(
5681                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5682                 "grantRuntimePermission");
5683 
5684         enforceCrossUserPermission(callingUid, userId,
5685                 true /* requireFullPermission */, true /* checkShell */,
5686                 "grantRuntimePermission");
5687 
5688         final int uid;
5689         final PackageSetting ps;
5690 
5691         synchronized (mPackages) {
5692             final PackageParser.Package pkg = mPackages.get(packageName);
5693             if (pkg == null) {
5694                 throw new IllegalArgumentException("Unknown package: " + packageName);
5695             }
5696             final BasePermission bp = mSettings.mPermissions.get(name);
5697             if (bp == null) {
5698                 throw new IllegalArgumentException("Unknown permission: " + name);
5699             }
5700             ps = (PackageSetting) pkg.mExtras;
5701             if (ps == null
5702                     || filterAppAccessLPr(ps, callingUid, userId)) {
5703                 throw new IllegalArgumentException("Unknown package: " + packageName);
5704             }
5705 
5706             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5707 
5708             // If a permission review is required for legacy apps we represent
5709             // their permissions as always granted runtime ones since we need
5710             // to keep the review required permission flag per user while an
5711             // install permission's state is shared across all users.
5712             if (mPermissionReviewRequired
5713                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5714                     && bp.isRuntime()) {
5715                 return;
5716             }
5717 
5718             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5719 
5720             final PermissionsState permissionsState = ps.getPermissionsState();
5721 
5722             final int flags = permissionsState.getPermissionFlags(name, userId);
5723             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5724                 throw new SecurityException("Cannot grant system fixed permission "
5725                         + name + " for package " + packageName);
5726             }
5727             if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5728                 throw new SecurityException("Cannot grant policy fixed permission "
5729                         + name + " for package " + packageName);
5730             }
5731 
5732             if (bp.isDevelopment()) {
5733                 // Development permissions must be handled specially, since they are not
5734                 // normal runtime permissions.  For now they apply to all users.
5735                 if (permissionsState.grantInstallPermission(bp) !=
5736                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
5737                     scheduleWriteSettingsLocked();
5738                 }
5739                 return;
5740             }
5741 
5742             if (ps.getInstantApp(userId) && !bp.isInstant()) {
5743                 throw new SecurityException("Cannot grant non-ephemeral permission"
5744                         + name + " for package " + packageName);
5745             }
5746 
5747             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5748                 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5749                 return;
5750             }
5751 
5752             final int result = permissionsState.grantRuntimePermission(bp, userId);
5753             switch (result) {
5754                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5755                     return;
5756                 }
5757 
5758                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5759                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5760                     mHandler.post(new Runnable() {
5761                         @Override
5762                         public void run() {
5763                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5764                         }
5765                     });
5766                 }
5767                 break;
5768             }
5769 
5770             if (bp.isRuntime()) {
5771                 logPermissionGranted(mContext, name, packageName);
5772             }
5773 
5774             mOnPermissionChangeListeners.onPermissionsChanged(uid);
5775 
5776             // Not critical if that is lost - app has to request again.
5777             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5778         }
5779 
5780         // Only need to do this if user is initialized. Otherwise it's a new user
5781         // and there are no processes running as the user yet and there's no need
5782         // to make an expensive call to remount processes for the changed permissions.
5783         if (READ_EXTERNAL_STORAGE.equals(name)
5784                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
5785             final long token = Binder.clearCallingIdentity();
5786             try {
5787                 if (sUserManager.isInitialized(userId)) {
5788                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
5789                             StorageManagerInternal.class);
5790                     storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5791                 }
5792             } finally {
5793                 Binder.restoreCallingIdentity(token);
5794             }
5795         }
5796     }
5797 
5798     @Override
revokeRuntimePermission(String packageName, String name, int userId)5799     public void revokeRuntimePermission(String packageName, String name, int userId) {
5800         revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5801     }
5802 
revokeRuntimePermission(String packageName, String name, int userId, boolean overridePolicy)5803     private void revokeRuntimePermission(String packageName, String name, int userId,
5804             boolean overridePolicy) {
5805         if (!sUserManager.exists(userId)) {
5806             Log.e(TAG, "No such user:" + userId);
5807             return;
5808         }
5809 
5810         mContext.enforceCallingOrSelfPermission(
5811                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5812                 "revokeRuntimePermission");
5813 
5814         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5815                 true /* requireFullPermission */, true /* checkShell */,
5816                 "revokeRuntimePermission");
5817 
5818         final int appId;
5819 
5820         synchronized (mPackages) {
5821             final PackageParser.Package pkg = mPackages.get(packageName);
5822             if (pkg == null) {
5823                 throw new IllegalArgumentException("Unknown package: " + packageName);
5824             }
5825             final PackageSetting ps = (PackageSetting) pkg.mExtras;
5826             if (ps == null
5827                     || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5828                 throw new IllegalArgumentException("Unknown package: " + packageName);
5829             }
5830             final BasePermission bp = mSettings.mPermissions.get(name);
5831             if (bp == null) {
5832                 throw new IllegalArgumentException("Unknown permission: " + name);
5833             }
5834 
5835             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5836 
5837             // If a permission review is required for legacy apps we represent
5838             // their permissions as always granted runtime ones since we need
5839             // to keep the review required permission flag per user while an
5840             // install permission's state is shared across all users.
5841             if (mPermissionReviewRequired
5842                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5843                     && bp.isRuntime()) {
5844                 return;
5845             }
5846 
5847             final PermissionsState permissionsState = ps.getPermissionsState();
5848 
5849             final int flags = permissionsState.getPermissionFlags(name, userId);
5850             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5851                 throw new SecurityException("Cannot revoke system fixed permission "
5852                         + name + " for package " + packageName);
5853             }
5854             if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5855                 throw new SecurityException("Cannot revoke policy fixed permission "
5856                         + name + " for package " + packageName);
5857             }
5858 
5859             if (bp.isDevelopment()) {
5860                 // Development permissions must be handled specially, since they are not
5861                 // normal runtime permissions.  For now they apply to all users.
5862                 if (permissionsState.revokeInstallPermission(bp) !=
5863                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
5864                     scheduleWriteSettingsLocked();
5865                 }
5866                 return;
5867             }
5868 
5869             if (permissionsState.revokeRuntimePermission(bp, userId) ==
5870                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
5871                 return;
5872             }
5873 
5874             if (bp.isRuntime()) {
5875                 logPermissionRevoked(mContext, name, packageName);
5876             }
5877 
5878             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5879 
5880             // Critical, after this call app should never have the permission.
5881             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5882 
5883             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5884         }
5885 
5886         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5887     }
5888 
5889     /**
5890      * We might auto-grant permissions if any permission of the group is already granted. Hence if
5891      * the group of a granted permission changes we need to revoke it to avoid having permissions of
5892      * the new group auto-granted.
5893      *
5894      * @param newPackage The new package that was installed
5895      * @param oldPackage The old package that was updated
5896      * @param allPackageNames All package names
5897      */
revokeRuntimePermissionsIfGroupChanged( PackageParser.Package newPackage, PackageParser.Package oldPackage, ArrayList<String> allPackageNames)5898     private void revokeRuntimePermissionsIfGroupChanged(
5899             PackageParser.Package newPackage,
5900             PackageParser.Package oldPackage,
5901             ArrayList<String> allPackageNames) {
5902         final int numOldPackagePermissions = oldPackage.permissions.size();
5903         final ArrayMap<String, String> oldPermissionNameToGroupName
5904                 = new ArrayMap<>(numOldPackagePermissions);
5905 
5906         for (int i = 0; i < numOldPackagePermissions; i++) {
5907             final PackageParser.Permission permission = oldPackage.permissions.get(i);
5908 
5909             if (permission.group != null) {
5910                 oldPermissionNameToGroupName.put(permission.info.name,
5911                         permission.group.info.name);
5912             }
5913         }
5914 
5915         final int numNewPackagePermissions = newPackage.permissions.size();
5916         for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
5917                 newPermissionNum++) {
5918             final PackageParser.Permission newPermission =
5919                     newPackage.permissions.get(newPermissionNum);
5920             final int newProtection = newPermission.info.protectionLevel;
5921 
5922             if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
5923                 final String permissionName = newPermission.info.name;
5924                 final String newPermissionGroupName =
5925                         newPermission.group == null ? null : newPermission.group.info.name;
5926                 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
5927                         permissionName);
5928 
5929                 if (newPermissionGroupName != null
5930                         && !newPermissionGroupName.equals(oldPermissionGroupName)) {
5931                     final List<UserInfo> users = mContext.getSystemService(UserManager.class)
5932                             .getUsers();
5933 
5934                     final int numUsers = users.size();
5935                     for (int userNum = 0; userNum < numUsers; userNum++) {
5936                         final int userId = users.get(userNum).id;
5937                         final int numPackages = allPackageNames.size();
5938 
5939                         for (int packageNum = 0; packageNum < numPackages; packageNum++) {
5940                             final String packageName = allPackageNames.get(packageNum);
5941 
5942                             if (checkPermission(permissionName, packageName, userId)
5943                                     == PackageManager.PERMISSION_GRANTED) {
5944                                 EventLog.writeEvent(0x534e4554, "72710897",
5945                                         newPackage.applicationInfo.uid,
5946                                         "Revoking permission", permissionName, "from package",
5947                                         packageName, "as the group changed from",
5948                                         oldPermissionGroupName, "to", newPermissionGroupName);
5949 
5950                                 try {
5951                                     revokeRuntimePermission(packageName, permissionName, userId,
5952                                            false);
5953                                 } catch (IllegalArgumentException e) {
5954                                     Slog.e(TAG, "Could not revoke " + permissionName + " from "
5955                                             + packageName, e);
5956                                 }
5957                             }
5958                         }
5959                     }
5960                 }
5961             }
5962         }
5963     }
5964 
5965 
5966     /**
5967      * Get the first event id for the permission.
5968      *
5969      * <p>There are four events for each permission: <ul>
5970      *     <li>Request permission: first id + 0</li>
5971      *     <li>Grant permission: first id + 1</li>
5972      *     <li>Request for permission denied: first id + 2</li>
5973      *     <li>Revoke permission: first id + 3</li>
5974      * </ul></p>
5975      *
5976      * @param name name of the permission
5977      *
5978      * @return The first event id for the permission
5979      */
getBaseEventId(@onNull String name)5980     private static int getBaseEventId(@NonNull String name) {
5981         int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5982 
5983         if (eventIdIndex == -1) {
5984             if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5985                     || Build.IS_USER) {
5986                 Log.i(TAG, "Unknown permission " + name);
5987 
5988                 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5989             } else {
5990                 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5991                 //
5992                 // Also update
5993                 // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5994                 // - metrics_constants.proto
5995                 throw new IllegalStateException("Unknown permission " + name);
5996             }
5997         }
5998 
5999         return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
6000     }
6001 
6002     /**
6003      * Log that a permission was revoked.
6004      *
6005      * @param context Context of the caller
6006      * @param name name of the permission
6007      * @param packageName package permission if for
6008      */
logPermissionRevoked(@onNull Context context, @NonNull String name, @NonNull String packageName)6009     private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
6010             @NonNull String packageName) {
6011         MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
6012     }
6013 
6014     /**
6015      * Log that a permission request was granted.
6016      *
6017      * @param context Context of the caller
6018      * @param name name of the permission
6019      * @param packageName package permission if for
6020      */
logPermissionGranted(@onNull Context context, @NonNull String name, @NonNull String packageName)6021     private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
6022             @NonNull String packageName) {
6023         MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
6024     }
6025 
6026     @Override
resetRuntimePermissions()6027     public void resetRuntimePermissions() {
6028         mContext.enforceCallingOrSelfPermission(
6029                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
6030                 "revokeRuntimePermission");
6031 
6032         int callingUid = Binder.getCallingUid();
6033         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
6034             mContext.enforceCallingOrSelfPermission(
6035                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6036                     "resetRuntimePermissions");
6037         }
6038 
6039         synchronized (mPackages) {
6040             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
6041             for (int userId : UserManagerService.getInstance().getUserIds()) {
6042                 final int packageCount = mPackages.size();
6043                 for (int i = 0; i < packageCount; i++) {
6044                     PackageParser.Package pkg = mPackages.valueAt(i);
6045                     if (!(pkg.mExtras instanceof PackageSetting)) {
6046                         continue;
6047                     }
6048                     PackageSetting ps = (PackageSetting) pkg.mExtras;
6049                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
6050                 }
6051             }
6052         }
6053     }
6054 
6055     @Override
getPermissionFlags(String name, String packageName, int userId)6056     public int getPermissionFlags(String name, String packageName, int userId) {
6057         if (!sUserManager.exists(userId)) {
6058             return 0;
6059         }
6060 
6061         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
6062 
6063         final int callingUid = Binder.getCallingUid();
6064         enforceCrossUserPermission(callingUid, userId,
6065                 true /* requireFullPermission */, false /* checkShell */,
6066                 "getPermissionFlags");
6067 
6068         synchronized (mPackages) {
6069             final PackageParser.Package pkg = mPackages.get(packageName);
6070             if (pkg == null) {
6071                 return 0;
6072             }
6073             final BasePermission bp = mSettings.mPermissions.get(name);
6074             if (bp == null) {
6075                 return 0;
6076             }
6077             final PackageSetting ps = (PackageSetting) pkg.mExtras;
6078             if (ps == null
6079                     || filterAppAccessLPr(ps, callingUid, userId)) {
6080                 return 0;
6081             }
6082             PermissionsState permissionsState = ps.getPermissionsState();
6083             return permissionsState.getPermissionFlags(name, userId);
6084         }
6085     }
6086 
6087     @Override
updatePermissionFlags(String name, String packageName, int flagMask, int flagValues, int userId)6088     public void updatePermissionFlags(String name, String packageName, int flagMask,
6089             int flagValues, int userId) {
6090         if (!sUserManager.exists(userId)) {
6091             return;
6092         }
6093 
6094         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
6095 
6096         final int callingUid = Binder.getCallingUid();
6097         enforceCrossUserPermission(callingUid, userId,
6098                 true /* requireFullPermission */, true /* checkShell */,
6099                 "updatePermissionFlags");
6100 
6101         // Only the system can change these flags and nothing else.
6102         if (getCallingUid() != Process.SYSTEM_UID) {
6103             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6104             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6105             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
6106             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
6107             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
6108         }
6109 
6110         synchronized (mPackages) {
6111             final PackageParser.Package pkg = mPackages.get(packageName);
6112             if (pkg == null) {
6113                 throw new IllegalArgumentException("Unknown package: " + packageName);
6114             }
6115             final PackageSetting ps = (PackageSetting) pkg.mExtras;
6116             if (ps == null
6117                     || filterAppAccessLPr(ps, callingUid, userId)) {
6118                 throw new IllegalArgumentException("Unknown package: " + packageName);
6119             }
6120 
6121             final BasePermission bp = mSettings.mPermissions.get(name);
6122             if (bp == null) {
6123                 throw new IllegalArgumentException("Unknown permission: " + name);
6124             }
6125 
6126             PermissionsState permissionsState = ps.getPermissionsState();
6127 
6128             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
6129 
6130             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
6131                 // Install and runtime permissions are stored in different places,
6132                 // so figure out what permission changed and persist the change.
6133                 if (permissionsState.getInstallPermissionState(name) != null) {
6134                     scheduleWriteSettingsLocked();
6135                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
6136                         || hadState) {
6137                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6138                 }
6139             }
6140         }
6141     }
6142 
6143     /**
6144      * Update the permission flags for all packages and runtime permissions of a user in order
6145      * to allow device or profile owner to remove POLICY_FIXED.
6146      */
6147     @Override
updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId)6148     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
6149         if (!sUserManager.exists(userId)) {
6150             return;
6151         }
6152 
6153         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
6154 
6155         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6156                 true /* requireFullPermission */, true /* checkShell */,
6157                 "updatePermissionFlagsForAllApps");
6158 
6159         // Only the system can change system fixed flags.
6160         if (getCallingUid() != Process.SYSTEM_UID) {
6161             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6162             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6163         }
6164 
6165         synchronized (mPackages) {
6166             boolean changed = false;
6167             final int packageCount = mPackages.size();
6168             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
6169                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
6170                 final PackageSetting ps = (PackageSetting) pkg.mExtras;
6171                 if (ps == null) {
6172                     continue;
6173                 }
6174                 PermissionsState permissionsState = ps.getPermissionsState();
6175                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
6176                         userId, flagMask, flagValues);
6177             }
6178             if (changed) {
6179                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6180             }
6181         }
6182     }
6183 
enforceGrantRevokeRuntimePermissionPermissions(String message)6184     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
6185         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
6186                 != PackageManager.PERMISSION_GRANTED
6187             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
6188                 != PackageManager.PERMISSION_GRANTED) {
6189             throw new SecurityException(message + " requires "
6190                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
6191                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
6192         }
6193     }
6194 
6195     @Override
shouldShowRequestPermissionRationale(String permissionName, String packageName, int userId)6196     public boolean shouldShowRequestPermissionRationale(String permissionName,
6197             String packageName, int userId) {
6198         if (UserHandle.getCallingUserId() != userId) {
6199             mContext.enforceCallingPermission(
6200                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6201                     "canShowRequestPermissionRationale for user " + userId);
6202         }
6203 
6204         final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
6205         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
6206             return false;
6207         }
6208 
6209         if (checkPermission(permissionName, packageName, userId)
6210                 == PackageManager.PERMISSION_GRANTED) {
6211             return false;
6212         }
6213 
6214         final int flags;
6215 
6216         final long identity = Binder.clearCallingIdentity();
6217         try {
6218             flags = getPermissionFlags(permissionName,
6219                     packageName, userId);
6220         } finally {
6221             Binder.restoreCallingIdentity(identity);
6222         }
6223 
6224         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
6225                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
6226                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
6227 
6228         if ((flags & fixedFlags) != 0) {
6229             return false;
6230         }
6231 
6232         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
6233     }
6234 
6235     @Override
addOnPermissionsChangeListener(IOnPermissionsChangeListener listener)6236     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6237         mContext.enforceCallingOrSelfPermission(
6238                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
6239                 "addOnPermissionsChangeListener");
6240 
6241         synchronized (mPackages) {
6242             mOnPermissionChangeListeners.addListenerLocked(listener);
6243         }
6244     }
6245 
6246     @Override
removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener)6247     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6248         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6249             throw new SecurityException("Instant applications don't have access to this method");
6250         }
6251         synchronized (mPackages) {
6252             mOnPermissionChangeListeners.removeListenerLocked(listener);
6253         }
6254     }
6255 
6256     @Override
isProtectedBroadcast(String actionName)6257     public boolean isProtectedBroadcast(String actionName) {
6258         // allow instant applications
6259         synchronized (mProtectedBroadcasts) {
6260             if (mProtectedBroadcasts.contains(actionName)) {
6261                 return true;
6262             } else if (actionName != null) {
6263                 // TODO: remove these terrible hacks
6264                 if (actionName.startsWith("android.net.netmon.lingerExpired")
6265                         || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6266                         || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6267                         || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6268                     return true;
6269                 }
6270             }
6271         }
6272         return false;
6273     }
6274 
6275     @Override
checkSignatures(String pkg1, String pkg2)6276     public int checkSignatures(String pkg1, String pkg2) {
6277         synchronized (mPackages) {
6278             final PackageParser.Package p1 = mPackages.get(pkg1);
6279             final PackageParser.Package p2 = mPackages.get(pkg2);
6280             if (p1 == null || p1.mExtras == null
6281                     || p2 == null || p2.mExtras == null) {
6282                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6283             }
6284             final int callingUid = Binder.getCallingUid();
6285             final int callingUserId = UserHandle.getUserId(callingUid);
6286             final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6287             final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6288             if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6289                     || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6290                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6291             }
6292             return compareSignatures(p1.mSignatures, p2.mSignatures);
6293         }
6294     }
6295 
6296     @Override
checkUidSignatures(int uid1, int uid2)6297     public int checkUidSignatures(int uid1, int uid2) {
6298         final int callingUid = Binder.getCallingUid();
6299         final int callingUserId = UserHandle.getUserId(callingUid);
6300         final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6301         // Map to base uids.
6302         uid1 = UserHandle.getAppId(uid1);
6303         uid2 = UserHandle.getAppId(uid2);
6304         // reader
6305         synchronized (mPackages) {
6306             Signature[] s1;
6307             Signature[] s2;
6308             Object obj = mSettings.getUserIdLPr(uid1);
6309             if (obj != null) {
6310                 if (obj instanceof SharedUserSetting) {
6311                     if (isCallerInstantApp) {
6312                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6313                     }
6314                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
6315                 } else if (obj instanceof PackageSetting) {
6316                     final PackageSetting ps = (PackageSetting) obj;
6317                     if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6318                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6319                     }
6320                     s1 = ps.signatures.mSignatures;
6321                 } else {
6322                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6323                 }
6324             } else {
6325                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6326             }
6327             obj = mSettings.getUserIdLPr(uid2);
6328             if (obj != null) {
6329                 if (obj instanceof SharedUserSetting) {
6330                     if (isCallerInstantApp) {
6331                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6332                     }
6333                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
6334                 } else if (obj instanceof PackageSetting) {
6335                     final PackageSetting ps = (PackageSetting) obj;
6336                     if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6337                         return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6338                     }
6339                     s2 = ps.signatures.mSignatures;
6340                 } else {
6341                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6342                 }
6343             } else {
6344                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6345             }
6346             return compareSignatures(s1, s2);
6347         }
6348     }
6349 
6350     /**
6351      * This method should typically only be used when granting or revoking
6352      * permissions, since the app may immediately restart after this call.
6353      * <p>
6354      * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6355      * guard your work against the app being relaunched.
6356      */
killUid(int appId, int userId, String reason)6357     private void killUid(int appId, int userId, String reason) {
6358         final long identity = Binder.clearCallingIdentity();
6359         try {
6360             IActivityManager am = ActivityManager.getService();
6361             if (am != null) {
6362                 try {
6363                     am.killUid(appId, userId, reason);
6364                 } catch (RemoteException e) {
6365                     /* ignore - same process */
6366                 }
6367             }
6368         } finally {
6369             Binder.restoreCallingIdentity(identity);
6370         }
6371     }
6372 
6373     /**
6374      * Compares two sets of signatures. Returns:
6375      * <br />
6376      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
6377      * <br />
6378      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
6379      * <br />
6380      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
6381      * <br />
6382      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
6383      * <br />
6384      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
6385      */
compareSignatures(Signature[] s1, Signature[] s2)6386     static int compareSignatures(Signature[] s1, Signature[] s2) {
6387         if (s1 == null) {
6388             return s2 == null
6389                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
6390                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
6391         }
6392 
6393         if (s2 == null) {
6394             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6395         }
6396 
6397         if (s1.length != s2.length) {
6398             return PackageManager.SIGNATURE_NO_MATCH;
6399         }
6400 
6401         // Since both signature sets are of size 1, we can compare without HashSets.
6402         if (s1.length == 1) {
6403             return s1[0].equals(s2[0]) ?
6404                     PackageManager.SIGNATURE_MATCH :
6405                     PackageManager.SIGNATURE_NO_MATCH;
6406         }
6407 
6408         ArraySet<Signature> set1 = new ArraySet<Signature>();
6409         for (Signature sig : s1) {
6410             set1.add(sig);
6411         }
6412         ArraySet<Signature> set2 = new ArraySet<Signature>();
6413         for (Signature sig : s2) {
6414             set2.add(sig);
6415         }
6416         // Make sure s2 contains all signatures in s1.
6417         if (set1.equals(set2)) {
6418             return PackageManager.SIGNATURE_MATCH;
6419         }
6420         return PackageManager.SIGNATURE_NO_MATCH;
6421     }
6422 
6423     /**
6424      * If the database version for this type of package (internal storage or
6425      * external storage) is less than the version where package signatures
6426      * were updated, return true.
6427      */
isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg)6428     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6429         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6430         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6431     }
6432 
6433     /**
6434      * Used for backward compatibility to make sure any packages with
6435      * certificate chains get upgraded to the new style. {@code existingSigs}
6436      * will be in the old format (since they were stored on disk from before the
6437      * system upgrade) and {@code scannedSigs} will be in the newer format.
6438      */
compareSignaturesCompat(PackageSignatures existingSigs, PackageParser.Package scannedPkg)6439     private int compareSignaturesCompat(PackageSignatures existingSigs,
6440             PackageParser.Package scannedPkg) {
6441         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6442             return PackageManager.SIGNATURE_NO_MATCH;
6443         }
6444 
6445         ArraySet<Signature> existingSet = new ArraySet<Signature>();
6446         for (Signature sig : existingSigs.mSignatures) {
6447             existingSet.add(sig);
6448         }
6449         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6450         for (Signature sig : scannedPkg.mSignatures) {
6451             try {
6452                 Signature[] chainSignatures = sig.getChainSignatures();
6453                 for (Signature chainSig : chainSignatures) {
6454                     scannedCompatSet.add(chainSig);
6455                 }
6456             } catch (CertificateEncodingException e) {
6457                 scannedCompatSet.add(sig);
6458             }
6459         }
6460         /*
6461          * Make sure the expanded scanned set contains all signatures in the
6462          * existing one.
6463          */
6464         if (scannedCompatSet.equals(existingSet)) {
6465             // Migrate the old signatures to the new scheme.
6466             existingSigs.assignSignatures(scannedPkg.mSignatures);
6467             // The new KeySets will be re-added later in the scanning process.
6468             synchronized (mPackages) {
6469                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6470             }
6471             return PackageManager.SIGNATURE_MATCH;
6472         }
6473         return PackageManager.SIGNATURE_NO_MATCH;
6474     }
6475 
isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg)6476     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6477         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6478         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6479     }
6480 
compareSignaturesRecover(PackageSignatures existingSigs, PackageParser.Package scannedPkg)6481     private int compareSignaturesRecover(PackageSignatures existingSigs,
6482             PackageParser.Package scannedPkg) {
6483         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6484             return PackageManager.SIGNATURE_NO_MATCH;
6485         }
6486 
6487         String msg = null;
6488         try {
6489             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6490                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6491                         + scannedPkg.packageName);
6492                 return PackageManager.SIGNATURE_MATCH;
6493             }
6494         } catch (CertificateException e) {
6495             msg = e.getMessage();
6496         }
6497 
6498         logCriticalInfo(Log.INFO,
6499                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6500         return PackageManager.SIGNATURE_NO_MATCH;
6501     }
6502 
6503     @Override
getAllPackages()6504     public List<String> getAllPackages() {
6505         final int callingUid = Binder.getCallingUid();
6506         final int callingUserId = UserHandle.getUserId(callingUid);
6507         synchronized (mPackages) {
6508             if (canViewInstantApps(callingUid, callingUserId)) {
6509                 return new ArrayList<String>(mPackages.keySet());
6510             }
6511             final String instantAppPkgName = getInstantAppPackageName(callingUid);
6512             final List<String> result = new ArrayList<>();
6513             if (instantAppPkgName != null) {
6514                 // caller is an instant application; filter unexposed applications
6515                 for (PackageParser.Package pkg : mPackages.values()) {
6516                     if (!pkg.visibleToInstantApps) {
6517                         continue;
6518                     }
6519                     result.add(pkg.packageName);
6520                 }
6521             } else {
6522                 // caller is a normal application; filter instant applications
6523                 for (PackageParser.Package pkg : mPackages.values()) {
6524                     final PackageSetting ps =
6525                             pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6526                     if (ps != null
6527                             && ps.getInstantApp(callingUserId)
6528                             && !mInstantAppRegistry.isInstantAccessGranted(
6529                                     callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6530                         continue;
6531                     }
6532                     result.add(pkg.packageName);
6533                 }
6534             }
6535             return result;
6536         }
6537     }
6538 
6539     @Override
getPackagesForUid(int uid)6540     public String[] getPackagesForUid(int uid) {
6541         final int callingUid = Binder.getCallingUid();
6542         final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6543         final int userId = UserHandle.getUserId(uid);
6544         uid = UserHandle.getAppId(uid);
6545         // reader
6546         synchronized (mPackages) {
6547             Object obj = mSettings.getUserIdLPr(uid);
6548             if (obj instanceof SharedUserSetting) {
6549                 if (isCallerInstantApp) {
6550                     return null;
6551                 }
6552                 final SharedUserSetting sus = (SharedUserSetting) obj;
6553                 final int N = sus.packages.size();
6554                 String[] res = new String[N];
6555                 final Iterator<PackageSetting> it = sus.packages.iterator();
6556                 int i = 0;
6557                 while (it.hasNext()) {
6558                     PackageSetting ps = it.next();
6559                     if (ps.getInstalled(userId)) {
6560                         res[i++] = ps.name;
6561                     } else {
6562                         res = ArrayUtils.removeElement(String.class, res, res[i]);
6563                     }
6564                 }
6565                 return res;
6566             } else if (obj instanceof PackageSetting) {
6567                 final PackageSetting ps = (PackageSetting) obj;
6568                 if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6569                     return new String[]{ps.name};
6570                 }
6571             }
6572         }
6573         return null;
6574     }
6575 
6576     @Override
getNameForUid(int uid)6577     public String getNameForUid(int uid) {
6578         final int callingUid = Binder.getCallingUid();
6579         if (getInstantAppPackageName(callingUid) != null) {
6580             return null;
6581         }
6582         synchronized (mPackages) {
6583             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6584             if (obj instanceof SharedUserSetting) {
6585                 final SharedUserSetting sus = (SharedUserSetting) obj;
6586                 return sus.name + ":" + sus.userId;
6587             } else if (obj instanceof PackageSetting) {
6588                 final PackageSetting ps = (PackageSetting) obj;
6589                 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6590                     return null;
6591                 }
6592                 return ps.name;
6593             }
6594             return null;
6595         }
6596     }
6597 
6598     @Override
getNamesForUids(int[] uids)6599     public String[] getNamesForUids(int[] uids) {
6600         if (uids == null || uids.length == 0) {
6601             return null;
6602         }
6603         final int callingUid = Binder.getCallingUid();
6604         if (getInstantAppPackageName(callingUid) != null) {
6605             return null;
6606         }
6607         final String[] names = new String[uids.length];
6608         synchronized (mPackages) {
6609             for (int i = uids.length - 1; i >= 0; i--) {
6610                 final int uid = uids[i];
6611                 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6612                 if (obj instanceof SharedUserSetting) {
6613                     final SharedUserSetting sus = (SharedUserSetting) obj;
6614                     names[i] = "shared:" + sus.name;
6615                 } else if (obj instanceof PackageSetting) {
6616                     final PackageSetting ps = (PackageSetting) obj;
6617                     if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6618                         names[i] = null;
6619                     } else {
6620                         names[i] = ps.name;
6621                     }
6622                 } else {
6623                     names[i] = null;
6624                 }
6625             }
6626         }
6627         return names;
6628     }
6629 
6630     @Override
getUidForSharedUser(String sharedUserName)6631     public int getUidForSharedUser(String sharedUserName) {
6632         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6633             return -1;
6634         }
6635         if (sharedUserName == null) {
6636             return -1;
6637         }
6638         // reader
6639         synchronized (mPackages) {
6640             SharedUserSetting suid;
6641             try {
6642                 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6643                 if (suid != null) {
6644                     return suid.userId;
6645                 }
6646             } catch (PackageManagerException ignore) {
6647                 // can't happen, but, still need to catch it
6648             }
6649             return -1;
6650         }
6651     }
6652 
6653     @Override
getFlagsForUid(int uid)6654     public int getFlagsForUid(int uid) {
6655         final int callingUid = Binder.getCallingUid();
6656         if (getInstantAppPackageName(callingUid) != null) {
6657             return 0;
6658         }
6659         synchronized (mPackages) {
6660             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6661             if (obj instanceof SharedUserSetting) {
6662                 final SharedUserSetting sus = (SharedUserSetting) obj;
6663                 return sus.pkgFlags;
6664             } else if (obj instanceof PackageSetting) {
6665                 final PackageSetting ps = (PackageSetting) obj;
6666                 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6667                     return 0;
6668                 }
6669                 return ps.pkgFlags;
6670             }
6671         }
6672         return 0;
6673     }
6674 
6675     @Override
getPrivateFlagsForUid(int uid)6676     public int getPrivateFlagsForUid(int uid) {
6677         final int callingUid = Binder.getCallingUid();
6678         if (getInstantAppPackageName(callingUid) != null) {
6679             return 0;
6680         }
6681         synchronized (mPackages) {
6682             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6683             if (obj instanceof SharedUserSetting) {
6684                 final SharedUserSetting sus = (SharedUserSetting) obj;
6685                 return sus.pkgPrivateFlags;
6686             } else if (obj instanceof PackageSetting) {
6687                 final PackageSetting ps = (PackageSetting) obj;
6688                 if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6689                     return 0;
6690                 }
6691                 return ps.pkgPrivateFlags;
6692             }
6693         }
6694         return 0;
6695     }
6696 
6697     @Override
isUidPrivileged(int uid)6698     public boolean isUidPrivileged(int uid) {
6699         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6700             return false;
6701         }
6702         uid = UserHandle.getAppId(uid);
6703         // reader
6704         synchronized (mPackages) {
6705             Object obj = mSettings.getUserIdLPr(uid);
6706             if (obj instanceof SharedUserSetting) {
6707                 final SharedUserSetting sus = (SharedUserSetting) obj;
6708                 final Iterator<PackageSetting> it = sus.packages.iterator();
6709                 while (it.hasNext()) {
6710                     if (it.next().isPrivileged()) {
6711                         return true;
6712                     }
6713                 }
6714             } else if (obj instanceof PackageSetting) {
6715                 final PackageSetting ps = (PackageSetting) obj;
6716                 return ps.isPrivileged();
6717             }
6718         }
6719         return false;
6720     }
6721 
6722     @Override
getAppOpPermissionPackages(String permissionName)6723     public String[] getAppOpPermissionPackages(String permissionName) {
6724         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6725             return null;
6726         }
6727         synchronized (mPackages) {
6728             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6729             if (pkgs == null) {
6730                 return null;
6731             }
6732             return pkgs.toArray(new String[pkgs.size()]);
6733         }
6734     }
6735 
6736     @Override
resolveIntent(Intent intent, String resolvedType, int flags, int userId)6737     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6738             int flags, int userId) {
6739         return resolveIntentInternal(
6740                 intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6741     }
6742 
resolveIntentInternal(Intent intent, String resolvedType, int flags, int userId, boolean resolveForStart)6743     private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6744             int flags, int userId, boolean resolveForStart) {
6745         try {
6746             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6747 
6748             if (!sUserManager.exists(userId)) return null;
6749             final int callingUid = Binder.getCallingUid();
6750             flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6751             enforceCrossUserPermission(callingUid, userId,
6752                     false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6753 
6754             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6755             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6756                     flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
6757             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6758 
6759             final ResolveInfo bestChoice =
6760                     chooseBestActivity(intent, resolvedType, flags, query, userId);
6761             return bestChoice;
6762         } finally {
6763             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6764         }
6765     }
6766 
6767     @Override
findPersistentPreferredActivity(Intent intent, int userId)6768     public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6769         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6770             throw new SecurityException(
6771                     "findPersistentPreferredActivity can only be run by the system");
6772         }
6773         if (!sUserManager.exists(userId)) {
6774             return null;
6775         }
6776         final int callingUid = Binder.getCallingUid();
6777         intent = updateIntentForResolve(intent);
6778         final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6779         final int flags = updateFlagsForResolve(
6780                 0, userId, intent, callingUid, false /*includeInstantApps*/);
6781         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6782                 userId);
6783         synchronized (mPackages) {
6784             return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6785                     userId);
6786         }
6787     }
6788 
6789     @Override
setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)6790     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6791             IntentFilter filter, int match, ComponentName activity) {
6792         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6793             return;
6794         }
6795         final int userId = UserHandle.getCallingUserId();
6796         if (DEBUG_PREFERRED) {
6797             Log.v(TAG, "setLastChosenActivity intent=" + intent
6798                 + " resolvedType=" + resolvedType
6799                 + " flags=" + flags
6800                 + " filter=" + filter
6801                 + " match=" + match
6802                 + " activity=" + activity);
6803             filter.dump(new PrintStreamPrinter(System.out), "    ");
6804         }
6805         intent.setComponent(null);
6806         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6807                 userId);
6808         // Find any earlier preferred or last chosen entries and nuke them
6809         findPreferredActivity(intent, resolvedType,
6810                 flags, query, 0, false, true, false, userId);
6811         // Add the new activity as the last chosen for this filter
6812         addPreferredActivityInternal(filter, match, null, activity, false, userId,
6813                 "Setting last chosen");
6814     }
6815 
6816     @Override
getLastChosenActivity(Intent intent, String resolvedType, int flags)6817     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6818         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6819             return null;
6820         }
6821         final int userId = UserHandle.getCallingUserId();
6822         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6823         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6824                 userId);
6825         return findPreferredActivity(intent, resolvedType, flags, query, 0,
6826                 false, false, false, userId);
6827     }
6828 
6829     /**
6830      * Returns whether or not instant apps have been disabled remotely.
6831      */
isEphemeralDisabled()6832     private boolean isEphemeralDisabled() {
6833         return mEphemeralAppsDisabled;
6834     }
6835 
isInstantAppAllowed( Intent intent, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck)6836     private boolean isInstantAppAllowed(
6837             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6838             boolean skipPackageCheck) {
6839         if (mInstantAppResolverConnection == null) {
6840             return false;
6841         }
6842         if (mInstantAppInstallerActivity == null) {
6843             return false;
6844         }
6845         if (intent.getComponent() != null) {
6846             return false;
6847         }
6848         if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6849             return false;
6850         }
6851         if (!skipPackageCheck && intent.getPackage() != null) {
6852             return false;
6853         }
6854         final boolean isWebUri = hasWebURI(intent);
6855         if (!isWebUri || intent.getData().getHost() == null) {
6856             return false;
6857         }
6858         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6859         // Or if there's already an ephemeral app installed that handles the action
6860         synchronized (mPackages) {
6861             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6862             for (int n = 0; n < count; n++) {
6863                 final ResolveInfo info = resolvedActivities.get(n);
6864                 final String packageName = info.activityInfo.packageName;
6865                 final PackageSetting ps = mSettings.mPackages.get(packageName);
6866                 if (ps != null) {
6867                     // only check domain verification status if the app is not a browser
6868                     if (!info.handleAllWebDataURI) {
6869                         // Try to get the status from User settings first
6870                         final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6871                         final int status = (int) (packedStatus >> 32);
6872                         if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6873                             || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6874                             if (DEBUG_EPHEMERAL) {
6875                                 Slog.v(TAG, "DENY instant app;"
6876                                     + " pkg: " + packageName + ", status: " + status);
6877                             }
6878                             return false;
6879                         }
6880                     }
6881                     if (ps.getInstantApp(userId)) {
6882                         if (DEBUG_EPHEMERAL) {
6883                             Slog.v(TAG, "DENY instant app installed;"
6884                                     + " pkg: " + packageName);
6885                         }
6886                         return false;
6887                     }
6888                 }
6889             }
6890         }
6891         // We've exhausted all ways to deny ephemeral application; let the system look for them.
6892         return true;
6893     }
6894 
requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, Intent origIntent, String resolvedType, String callingPackage, Bundle verificationBundle, int userId)6895     private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6896             Intent origIntent, String resolvedType, String callingPackage,
6897             Bundle verificationBundle, int userId) {
6898         final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6899                 new InstantAppRequest(responseObj, origIntent, resolvedType,
6900                         callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6901         mHandler.sendMessage(msg);
6902     }
6903 
chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int userId)6904     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6905             int flags, List<ResolveInfo> query, int userId) {
6906         if (query != null) {
6907             final int N = query.size();
6908             if (N == 1) {
6909                 return query.get(0);
6910             } else if (N > 1) {
6911                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6912                 // If there is more than one activity with the same priority,
6913                 // then let the user decide between them.
6914                 ResolveInfo r0 = query.get(0);
6915                 ResolveInfo r1 = query.get(1);
6916                 if (DEBUG_INTENT_MATCHING || debug) {
6917                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6918                             + r1.activityInfo.name + "=" + r1.priority);
6919                 }
6920                 // If the first activity has a higher priority, or a different
6921                 // default, then it is always desirable to pick it.
6922                 if (r0.priority != r1.priority
6923                         || r0.preferredOrder != r1.preferredOrder
6924                         || r0.isDefault != r1.isDefault) {
6925                     return query.get(0);
6926                 }
6927                 // If we have saved a preference for a preferred activity for
6928                 // this Intent, use that.
6929                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6930                         flags, query, r0.priority, true, false, debug, userId);
6931                 if (ri != null) {
6932                     return ri;
6933                 }
6934                 // If we have an ephemeral app, use it
6935                 for (int i = 0; i < N; i++) {
6936                     ri = query.get(i);
6937                     if (ri.activityInfo.applicationInfo.isInstantApp()) {
6938                         final String packageName = ri.activityInfo.packageName;
6939                         final PackageSetting ps = mSettings.mPackages.get(packageName);
6940                         final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6941                         final int status = (int)(packedStatus >> 32);
6942                         if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6943                             return ri;
6944                         }
6945                     }
6946                 }
6947                 ri = new ResolveInfo(mResolveInfo);
6948                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
6949                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6950                 // If all of the options come from the same package, show the application's
6951                 // label and icon instead of the generic resolver's.
6952                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6953                 // and then throw away the ResolveInfo itself, meaning that the caller loses
6954                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6955                 // a fallback for this case; we only set the target package's resources on
6956                 // the ResolveInfo, not the ActivityInfo.
6957                 final String intentPackage = intent.getPackage();
6958                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6959                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6960                     ri.resolvePackageName = intentPackage;
6961                     if (userNeedsBadging(userId)) {
6962                         ri.noResourceId = true;
6963                     } else {
6964                         ri.icon = appi.icon;
6965                     }
6966                     ri.iconResourceId = appi.icon;
6967                     ri.labelRes = appi.labelRes;
6968                 }
6969                 ri.activityInfo.applicationInfo = new ApplicationInfo(
6970                         ri.activityInfo.applicationInfo);
6971                 if (userId != 0) {
6972                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6973                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6974                 }
6975                 // Make sure that the resolver is displayable in car mode
6976                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6977                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6978                 return ri;
6979             }
6980         }
6981         return null;
6982     }
6983 
6984     /**
6985      * Return true if the given list is not empty and all of its contents have
6986      * an activityInfo with the given package name.
6987      */
allHavePackage(List<ResolveInfo> list, String packageName)6988     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6989         if (ArrayUtils.isEmpty(list)) {
6990             return false;
6991         }
6992         for (int i = 0, N = list.size(); i < N; i++) {
6993             final ResolveInfo ri = list.get(i);
6994             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6995             if (ai == null || !packageName.equals(ai.packageName)) {
6996                 return false;
6997             }
6998         }
6999         return true;
7000     }
7001 
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)7002     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
7003             int flags, List<ResolveInfo> query, boolean debug, int userId) {
7004         final int N = query.size();
7005         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
7006                 .get(userId);
7007         // Get the list of persistent preferred activities that handle the intent
7008         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
7009         List<PersistentPreferredActivity> pprefs = ppir != null
7010                 ? ppir.queryIntent(intent, resolvedType,
7011                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
7012                         userId)
7013                 : null;
7014         if (pprefs != null && pprefs.size() > 0) {
7015             final int M = pprefs.size();
7016             for (int i=0; i<M; i++) {
7017                 final PersistentPreferredActivity ppa = pprefs.get(i);
7018                 if (DEBUG_PREFERRED || debug) {
7019                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
7020                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
7021                             + "\n  component=" + ppa.mComponent);
7022                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7023                 }
7024                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
7025                         flags | MATCH_DISABLED_COMPONENTS, userId);
7026                 if (DEBUG_PREFERRED || debug) {
7027                     Slog.v(TAG, "Found persistent preferred activity:");
7028                     if (ai != null) {
7029                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7030                     } else {
7031                         Slog.v(TAG, "  null");
7032                     }
7033                 }
7034                 if (ai == null) {
7035                     // This previously registered persistent preferred activity
7036                     // component is no longer known. Ignore it and do NOT remove it.
7037                     continue;
7038                 }
7039                 for (int j=0; j<N; j++) {
7040                     final ResolveInfo ri = query.get(j);
7041                     if (!ri.activityInfo.applicationInfo.packageName
7042                             .equals(ai.applicationInfo.packageName)) {
7043                         continue;
7044                     }
7045                     if (!ri.activityInfo.name.equals(ai.name)) {
7046                         continue;
7047                     }
7048                     //  Found a persistent preference that can handle the intent.
7049                     if (DEBUG_PREFERRED || debug) {
7050                         Slog.v(TAG, "Returning persistent preferred activity: " +
7051                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7052                     }
7053                     return ri;
7054                 }
7055             }
7056         }
7057         return null;
7058     }
7059 
7060     // TODO: handle preferred activities missing while user has amnesia
findPreferredActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)7061     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
7062             List<ResolveInfo> query, int priority, boolean always,
7063             boolean removeMatches, boolean debug, int userId) {
7064         if (!sUserManager.exists(userId)) return null;
7065         final int callingUid = Binder.getCallingUid();
7066         flags = updateFlagsForResolve(
7067                 flags, userId, intent, callingUid, false /*includeInstantApps*/);
7068         intent = updateIntentForResolve(intent);
7069         // writer
7070         synchronized (mPackages) {
7071             // Try to find a matching persistent preferred activity.
7072             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
7073                     debug, userId);
7074 
7075             // If a persistent preferred activity matched, use it.
7076             if (pri != null) {
7077                 return pri;
7078             }
7079 
7080             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
7081             // Get the list of preferred activities that handle the intent
7082             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
7083             List<PreferredActivity> prefs = pir != null
7084                     ? pir.queryIntent(intent, resolvedType,
7085                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
7086                             userId)
7087                     : null;
7088             if (prefs != null && prefs.size() > 0) {
7089                 boolean changed = false;
7090                 try {
7091                     // First figure out how good the original match set is.
7092                     // We will only allow preferred activities that came
7093                     // from the same match quality.
7094                     int match = 0;
7095 
7096                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
7097 
7098                     final int N = query.size();
7099                     for (int j=0; j<N; j++) {
7100                         final ResolveInfo ri = query.get(j);
7101                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
7102                                 + ": 0x" + Integer.toHexString(match));
7103                         if (ri.match > match) {
7104                             match = ri.match;
7105                         }
7106                     }
7107 
7108                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
7109                             + Integer.toHexString(match));
7110 
7111                     match &= IntentFilter.MATCH_CATEGORY_MASK;
7112                     final int M = prefs.size();
7113                     for (int i=0; i<M; i++) {
7114                         final PreferredActivity pa = prefs.get(i);
7115                         if (DEBUG_PREFERRED || debug) {
7116                             Slog.v(TAG, "Checking PreferredActivity ds="
7117                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
7118                                     + "\n  component=" + pa.mPref.mComponent);
7119                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7120                         }
7121                         if (pa.mPref.mMatch != match) {
7122                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
7123                                     + Integer.toHexString(pa.mPref.mMatch));
7124                             continue;
7125                         }
7126                         // If it's not an "always" type preferred activity and that's what we're
7127                         // looking for, skip it.
7128                         if (always && !pa.mPref.mAlways) {
7129                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
7130                             continue;
7131                         }
7132                         final ActivityInfo ai = getActivityInfo(
7133                                 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
7134                                         | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
7135                                 userId);
7136                         if (DEBUG_PREFERRED || debug) {
7137                             Slog.v(TAG, "Found preferred activity:");
7138                             if (ai != null) {
7139                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7140                             } else {
7141                                 Slog.v(TAG, "  null");
7142                             }
7143                         }
7144                         if (ai == null) {
7145                             // This previously registered preferred activity
7146                             // component is no longer known.  Most likely an update
7147                             // to the app was installed and in the new version this
7148                             // component no longer exists.  Clean it up by removing
7149                             // it from the preferred activities list, and skip it.
7150                             Slog.w(TAG, "Removing dangling preferred activity: "
7151                                     + pa.mPref.mComponent);
7152                             pir.removeFilter(pa);
7153                             changed = true;
7154                             continue;
7155                         }
7156                         for (int j=0; j<N; j++) {
7157                             final ResolveInfo ri = query.get(j);
7158                             if (!ri.activityInfo.applicationInfo.packageName
7159                                     .equals(ai.applicationInfo.packageName)) {
7160                                 continue;
7161                             }
7162                             if (!ri.activityInfo.name.equals(ai.name)) {
7163                                 continue;
7164                             }
7165 
7166                             if (removeMatches) {
7167                                 pir.removeFilter(pa);
7168                                 changed = true;
7169                                 if (DEBUG_PREFERRED) {
7170                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
7171                                 }
7172                                 break;
7173                             }
7174 
7175                             // Okay we found a previously set preferred or last chosen app.
7176                             // If the result set is different from when this
7177                             // was created, and is not a subset of the preferred set, we need to
7178                             // clear it and re-ask the user their preference, if we're looking for
7179                             // an "always" type entry.
7180                             if (always && !pa.mPref.sameSet(query)) {
7181                                 if (pa.mPref.isSuperset(query)) {
7182                                     // some components of the set are no longer present in
7183                                     // the query, but the preferred activity can still be reused
7184                                     if (DEBUG_PREFERRED) {
7185                                         Slog.i(TAG, "Result set changed, but PreferredActivity is"
7186                                                 + " still valid as only non-preferred components"
7187                                                 + " were removed for " + intent + " type "
7188                                                 + resolvedType);
7189                                     }
7190                                     // remove obsolete components and re-add the up-to-date filter
7191                                     PreferredActivity freshPa = new PreferredActivity(pa,
7192                                             pa.mPref.mMatch,
7193                                             pa.mPref.discardObsoleteComponents(query),
7194                                             pa.mPref.mComponent,
7195                                             pa.mPref.mAlways);
7196                                     pir.removeFilter(pa);
7197                                     pir.addFilter(freshPa);
7198                                     changed = true;
7199                                 } else {
7200                                     Slog.i(TAG,
7201                                             "Result set changed, dropping preferred activity for "
7202                                                     + intent + " type " + resolvedType);
7203                                     if (DEBUG_PREFERRED) {
7204                                         Slog.v(TAG, "Removing preferred activity since set changed "
7205                                                 + pa.mPref.mComponent);
7206                                     }
7207                                     pir.removeFilter(pa);
7208                                     // Re-add the filter as a "last chosen" entry (!always)
7209                                     PreferredActivity lastChosen = new PreferredActivity(
7210                                             pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
7211                                     pir.addFilter(lastChosen);
7212                                     changed = true;
7213                                     return null;
7214                                 }
7215                             }
7216 
7217                             // Yay! Either the set matched or we're looking for the last chosen
7218                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
7219                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7220                             return ri;
7221                         }
7222                     }
7223                 } finally {
7224                     if (changed) {
7225                         if (DEBUG_PREFERRED) {
7226                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
7227                         }
7228                         scheduleWritePackageRestrictionsLocked(userId);
7229                     }
7230                 }
7231             }
7232         }
7233         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
7234         return null;
7235     }
7236 
7237     /*
7238      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
7239      */
7240     @Override
canForwardTo(Intent intent, String resolvedType, int sourceUserId, int targetUserId)7241     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
7242             int targetUserId) {
7243         mContext.enforceCallingOrSelfPermission(
7244                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
7245         List<CrossProfileIntentFilter> matches =
7246                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7247         if (matches != null) {
7248             int size = matches.size();
7249             for (int i = 0; i < size; i++) {
7250                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
7251             }
7252         }
7253         if (hasWebURI(intent)) {
7254             // cross-profile app linking works only towards the parent.
7255             final int callingUid = Binder.getCallingUid();
7256             final UserInfo parent = getProfileParent(sourceUserId);
7257             synchronized(mPackages) {
7258                 int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7259                         false /*includeInstantApps*/);
7260                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7261                         intent, resolvedType, flags, sourceUserId, parent.id);
7262                 return xpDomainInfo != null;
7263             }
7264         }
7265         return false;
7266     }
7267 
getProfileParent(int userId)7268     private UserInfo getProfileParent(int userId) {
7269         final long identity = Binder.clearCallingIdentity();
7270         try {
7271             return sUserManager.getProfileParent(userId);
7272         } finally {
7273             Binder.restoreCallingIdentity(identity);
7274         }
7275     }
7276 
getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)7277     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7278             String resolvedType, int userId) {
7279         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7280         if (resolver != null) {
7281             return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7282         }
7283         return null;
7284     }
7285 
7286     @Override
queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)7287     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7288             String resolvedType, int flags, int userId) {
7289         try {
7290             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7291 
7292             return new ParceledListSlice<>(
7293                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7294         } finally {
7295             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7296         }
7297     }
7298 
7299     /**
7300      * Returns the package name of the calling Uid if it's an instant app. If it isn't
7301      * instant, returns {@code null}.
7302      */
getInstantAppPackageName(int callingUid)7303     private String getInstantAppPackageName(int callingUid) {
7304         synchronized (mPackages) {
7305             // If the caller is an isolated app use the owner's uid for the lookup.
7306             if (Process.isIsolated(callingUid)) {
7307                 callingUid = mIsolatedOwners.get(callingUid);
7308             }
7309             final int appId = UserHandle.getAppId(callingUid);
7310             final Object obj = mSettings.getUserIdLPr(appId);
7311             if (obj instanceof PackageSetting) {
7312                 final PackageSetting ps = (PackageSetting) obj;
7313                 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7314                 return isInstantApp ? ps.pkg.packageName : null;
7315             }
7316         }
7317         return null;
7318     }
7319 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId)7320     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7321             String resolvedType, int flags, int userId) {
7322         return queryIntentActivitiesInternal(
7323                 intent, resolvedType, flags, Binder.getCallingUid(), userId,
7324                 false /*resolveForStart*/, true /*allowDynamicSplits*/);
7325     }
7326 
queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits)7327     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7328             String resolvedType, int flags, int filterCallingUid, int userId,
7329             boolean resolveForStart, boolean allowDynamicSplits) {
7330         if (!sUserManager.exists(userId)) return Collections.emptyList();
7331         final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7332         enforceCrossUserPermission(Binder.getCallingUid(), userId,
7333                 false /* requireFullPermission */, false /* checkShell */,
7334                 "query intent activities");
7335         final String pkgName = intent.getPackage();
7336         ComponentName comp = intent.getComponent();
7337         if (comp == null) {
7338             if (intent.getSelector() != null) {
7339                 intent = intent.getSelector();
7340                 comp = intent.getComponent();
7341             }
7342         }
7343 
7344         flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7345                 comp != null || pkgName != null /*onlyExposedExplicitly*/);
7346         if (comp != null) {
7347             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7348             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7349             if (ai != null) {
7350                 // When specifying an explicit component, we prevent the activity from being
7351                 // used when either 1) the calling package is normal and the activity is within
7352                 // an ephemeral application or 2) the calling package is ephemeral and the
7353                 // activity is not visible to ephemeral applications.
7354                 final boolean matchInstantApp =
7355                         (flags & PackageManager.MATCH_INSTANT) != 0;
7356                 final boolean matchVisibleToInstantAppOnly =
7357                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7358                 final boolean matchExplicitlyVisibleOnly =
7359                         (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7360                 final boolean isCallerInstantApp =
7361                         instantAppPkgName != null;
7362                 final boolean isTargetSameInstantApp =
7363                         comp.getPackageName().equals(instantAppPkgName);
7364                 final boolean isTargetInstantApp =
7365                         (ai.applicationInfo.privateFlags
7366                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7367                 final boolean isTargetVisibleToInstantApp =
7368                         (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7369                 final boolean isTargetExplicitlyVisibleToInstantApp =
7370                         isTargetVisibleToInstantApp
7371                         && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7372                 final boolean isTargetHiddenFromInstantApp =
7373                         !isTargetVisibleToInstantApp
7374                         || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7375                 final boolean blockResolution =
7376                         !isTargetSameInstantApp
7377                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7378                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
7379                                         && isTargetHiddenFromInstantApp));
7380                 if (!blockResolution) {
7381                     final ResolveInfo ri = new ResolveInfo();
7382                     ri.activityInfo = ai;
7383                     list.add(ri);
7384                 }
7385             }
7386             return applyPostResolutionFilter(
7387                     list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7388         }
7389 
7390         // reader
7391         boolean sortResult = false;
7392         boolean addEphemeral = false;
7393         List<ResolveInfo> result;
7394         final boolean ephemeralDisabled = isEphemeralDisabled();
7395         synchronized (mPackages) {
7396             if (pkgName == null) {
7397                 List<CrossProfileIntentFilter> matchingFilters =
7398                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7399                 // Check for results that need to skip the current profile.
7400                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
7401                         resolvedType, flags, userId);
7402                 if (xpResolveInfo != null) {
7403                     List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
7404                     xpResult.add(xpResolveInfo);
7405                     return applyPostResolutionFilter(
7406                             filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
7407                             allowDynamicSplits, filterCallingUid, userId);
7408                 }
7409 
7410                 // Check for results in the current profile.
7411                 result = filterIfNotSystemUser(mActivities.queryIntent(
7412                         intent, resolvedType, flags, userId), userId);
7413                 addEphemeral = !ephemeralDisabled
7414                         && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
7415                 // Check for cross profile results.
7416                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7417                 xpResolveInfo = queryCrossProfileIntents(
7418                         matchingFilters, intent, resolvedType, flags, userId,
7419                         hasNonNegativePriorityResult);
7420                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7421                     boolean isVisibleToUser = filterIfNotSystemUser(
7422                             Collections.singletonList(xpResolveInfo), userId).size() > 0;
7423                     if (isVisibleToUser) {
7424                         result.add(xpResolveInfo);
7425                         sortResult = true;
7426                     }
7427                 }
7428                 if (hasWebURI(intent)) {
7429                     CrossProfileDomainInfo xpDomainInfo = null;
7430                     final UserInfo parent = getProfileParent(userId);
7431                     if (parent != null) {
7432                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7433                                 flags, userId, parent.id);
7434                     }
7435                     if (xpDomainInfo != null) {
7436                         if (xpResolveInfo != null) {
7437                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
7438                             // in the result.
7439                             result.remove(xpResolveInfo);
7440                         }
7441                         if (result.size() == 0 && !addEphemeral) {
7442                             // No result in current profile, but found candidate in parent user.
7443                             // And we are not going to add emphemeral app, so we can return the
7444                             // result straight away.
7445                             result.add(xpDomainInfo.resolveInfo);
7446                             return applyPostResolutionFilter(result, instantAppPkgName,
7447                                     allowDynamicSplits, filterCallingUid, userId);
7448                         }
7449                     } else if (result.size() <= 1 && !addEphemeral) {
7450                         // No result in parent user and <= 1 result in current profile, and we
7451                         // are not going to add emphemeral app, so we can return the result without
7452                         // further processing.
7453                         return applyPostResolutionFilter(result, instantAppPkgName,
7454                                 allowDynamicSplits, filterCallingUid, userId);
7455                     }
7456                     // We have more than one candidate (combining results from current and parent
7457                     // profile), so we need filtering and sorting.
7458                     result = filterCandidatesWithDomainPreferredActivitiesLPr(
7459                             intent, flags, result, xpDomainInfo, userId);
7460                     sortResult = true;
7461                 }
7462             } else {
7463                 final PackageParser.Package pkg = mPackages.get(pkgName);
7464                 result = null;
7465                 if (pkg != null) {
7466                     result = filterIfNotSystemUser(
7467                             mActivities.queryIntentForPackage(
7468                                     intent, resolvedType, flags, pkg.activities, userId),
7469                             userId);
7470                 }
7471                 if (result == null || result.size() == 0) {
7472                     // the caller wants to resolve for a particular package; however, there
7473                     // were no installed results, so, try to find an ephemeral result
7474                     addEphemeral = !ephemeralDisabled
7475                             && isInstantAppAllowed(
7476                                     intent, null /*result*/, userId, true /*skipPackageCheck*/);
7477                     if (result == null) {
7478                         result = new ArrayList<>();
7479                     }
7480                 }
7481             }
7482         }
7483         if (addEphemeral) {
7484             result = maybeAddInstantAppInstaller(
7485                     result, intent, resolvedType, flags, userId, resolveForStart);
7486         }
7487         if (sortResult) {
7488             Collections.sort(result, mResolvePrioritySorter);
7489         }
7490         return applyPostResolutionFilter(
7491                 result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7492     }
7493 
maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent, String resolvedType, int flags, int userId, boolean resolveForStart)7494     private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7495             String resolvedType, int flags, int userId, boolean resolveForStart) {
7496         // first, check to see if we've got an instant app already installed
7497         final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7498         ResolveInfo localInstantApp = null;
7499         boolean blockResolution = false;
7500         if (!alreadyResolvedLocally) {
7501             final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7502                     flags
7503                         | PackageManager.GET_RESOLVED_FILTER
7504                         | PackageManager.MATCH_INSTANT
7505                         | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7506                     userId);
7507             for (int i = instantApps.size() - 1; i >= 0; --i) {
7508                 final ResolveInfo info = instantApps.get(i);
7509                 final String packageName = info.activityInfo.packageName;
7510                 final PackageSetting ps = mSettings.mPackages.get(packageName);
7511                 if (ps.getInstantApp(userId)) {
7512                     final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7513                     final int status = (int)(packedStatus >> 32);
7514                     final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7515                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7516                         // there's a local instant application installed, but, the user has
7517                         // chosen to never use it; skip resolution and don't acknowledge
7518                         // an instant application is even available
7519                         if (DEBUG_EPHEMERAL) {
7520                             Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7521                         }
7522                         blockResolution = true;
7523                         break;
7524                     } else {
7525                         // we have a locally installed instant application; skip resolution
7526                         // but acknowledge there's an instant application available
7527                         if (DEBUG_EPHEMERAL) {
7528                             Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7529                         }
7530                         localInstantApp = info;
7531                         break;
7532                     }
7533                 }
7534             }
7535         }
7536         // no app installed, let's see if one's available
7537         AuxiliaryResolveInfo auxiliaryResponse = null;
7538         if (!blockResolution) {
7539             if (localInstantApp == null) {
7540                 // we don't have an instant app locally, resolve externally
7541                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7542                 final InstantAppRequest requestObject = new InstantAppRequest(
7543                         null /*responseObj*/, intent /*origIntent*/, resolvedType,
7544                         null /*callingPackage*/, userId, null /*verificationBundle*/,
7545                         resolveForStart);
7546                 auxiliaryResponse =
7547                         InstantAppResolver.doInstantAppResolutionPhaseOne(
7548                                 mContext, mInstantAppResolverConnection, requestObject);
7549                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7550             } else {
7551                 // we have an instant application locally, but, we can't admit that since
7552                 // callers shouldn't be able to determine prior browsing. create a dummy
7553                 // auxiliary response so the downstream code behaves as if there's an
7554                 // instant application available externally. when it comes time to start
7555                 // the instant application, we'll do the right thing.
7556                 final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7557                 auxiliaryResponse = new AuxiliaryResolveInfo(
7558                         ai.packageName, null /*splitName*/, null /*failureActivity*/,
7559                         ai.versionCode, null /*failureIntent*/);
7560             }
7561         }
7562         if (auxiliaryResponse != null) {
7563             if (DEBUG_EPHEMERAL) {
7564                 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7565             }
7566             final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7567             final PackageSetting ps =
7568                     mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7569             if (ps != null) {
7570                 ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7571                         mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7572                 ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7573                 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7574                 // make sure this resolver is the default
7575                 ephemeralInstaller.isDefault = true;
7576                 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7577                         | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7578                 // add a non-generic filter
7579                 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7580                 ephemeralInstaller.filter.addDataPath(
7581                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7582                 ephemeralInstaller.isInstantAppAvailable = true;
7583                 result.add(ephemeralInstaller);
7584             }
7585         }
7586         return result;
7587     }
7588 
7589     private static class CrossProfileDomainInfo {
7590         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7591         ResolveInfo resolveInfo;
7592         /* Best domain verification status of the activities found in the other profile */
7593         int bestDomainVerificationStatus;
7594     }
7595 
getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, int flags, int sourceUserId, int parentUserId)7596     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7597             String resolvedType, int flags, int sourceUserId, int parentUserId) {
7598         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7599                 sourceUserId)) {
7600             return null;
7601         }
7602         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7603                 resolvedType, flags, parentUserId);
7604 
7605         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7606             return null;
7607         }
7608         CrossProfileDomainInfo result = null;
7609         int size = resultTargetUser.size();
7610         for (int i = 0; i < size; i++) {
7611             ResolveInfo riTargetUser = resultTargetUser.get(i);
7612             // Intent filter verification is only for filters that specify a host. So don't return
7613             // those that handle all web uris.
7614             if (riTargetUser.handleAllWebDataURI) {
7615                 continue;
7616             }
7617             String packageName = riTargetUser.activityInfo.packageName;
7618             PackageSetting ps = mSettings.mPackages.get(packageName);
7619             if (ps == null) {
7620                 continue;
7621             }
7622             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7623             int status = (int)(verificationState >> 32);
7624             if (result == null) {
7625                 result = new CrossProfileDomainInfo();
7626                 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7627                         sourceUserId, parentUserId);
7628                 result.bestDomainVerificationStatus = status;
7629             } else {
7630                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7631                         result.bestDomainVerificationStatus);
7632             }
7633         }
7634         // Don't consider matches with status NEVER across profiles.
7635         if (result != null && result.bestDomainVerificationStatus
7636                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7637             return null;
7638         }
7639         return result;
7640     }
7641 
7642     /**
7643      * Verification statuses are ordered from the worse to the best, except for
7644      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7645      */
bestDomainVerificationStatus(int status1, int status2)7646     private int bestDomainVerificationStatus(int status1, int status2) {
7647         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7648             return status2;
7649         }
7650         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7651             return status1;
7652         }
7653         return (int) MathUtils.max(status1, status2);
7654     }
7655 
isUserEnabled(int userId)7656     private boolean isUserEnabled(int userId) {
7657         long callingId = Binder.clearCallingIdentity();
7658         try {
7659             UserInfo userInfo = sUserManager.getUserInfo(userId);
7660             return userInfo != null && userInfo.isEnabled();
7661         } finally {
7662             Binder.restoreCallingIdentity(callingId);
7663         }
7664     }
7665 
7666     /**
7667      * Filter out activities with systemUserOnly flag set, when current user is not System.
7668      *
7669      * @return filtered list
7670      */
filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId)7671     private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7672         if (userId == UserHandle.USER_SYSTEM) {
7673             return resolveInfos;
7674         }
7675         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7676             ResolveInfo info = resolveInfos.get(i);
7677             if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7678                 resolveInfos.remove(i);
7679             }
7680         }
7681         return resolveInfos;
7682     }
7683 
7684     /**
7685      * Filters out ephemeral activities.
7686      * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7687      * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7688      *
7689      * @param resolveInfos The pre-filtered list of resolved activities
7690      * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7691      *          is performed.
7692      * @return A filtered list of resolved activities.
7693      */
applyPostResolutionFilter(List<ResolveInfo> resolveInfos, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId)7694     private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7695             String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
7696         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7697             final ResolveInfo info = resolveInfos.get(i);
7698             // allow activities that are defined in the provided package
7699             if (allowDynamicSplits
7700                     && info.activityInfo.splitName != null
7701                     && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7702                             info.activityInfo.splitName)) {
7703                 if (mInstantAppInstallerInfo == null) {
7704                     if (DEBUG_INSTALL) {
7705                         Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
7706                     }
7707                     resolveInfos.remove(i);
7708                     continue;
7709                 }
7710                 // requested activity is defined in a split that hasn't been installed yet.
7711                 // add the installer to the resolve list
7712                 if (DEBUG_INSTALL) {
7713                     Slog.v(TAG, "Adding installer to the ResolveInfo list");
7714                 }
7715                 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7716                 final ComponentName installFailureActivity = findInstallFailureActivity(
7717                         info.activityInfo.packageName,  filterCallingUid, userId);
7718                 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7719                         info.activityInfo.packageName, info.activityInfo.splitName,
7720                         installFailureActivity,
7721                         info.activityInfo.applicationInfo.versionCode,
7722                         null /*failureIntent*/);
7723                 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7724                         | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7725                 // add a non-generic filter
7726                 installerInfo.filter = new IntentFilter();
7727 
7728                 // This resolve info may appear in the chooser UI, so let us make it
7729                 // look as the one it replaces as far as the user is concerned which
7730                 // requires loading the correct label and icon for the resolve info.
7731                 installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7732                 installerInfo.labelRes = info.resolveLabelResId();
7733                 installerInfo.icon = info.resolveIconResId();
7734 
7735                 // propagate priority/preferred order/default
7736                 installerInfo.priority = info.priority;
7737                 installerInfo.preferredOrder = info.preferredOrder;
7738                 installerInfo.isDefault = info.isDefault;
7739                 resolveInfos.set(i, installerInfo);
7740                 continue;
7741             }
7742             // caller is a full app, don't need to apply any other filtering
7743             if (ephemeralPkgName == null) {
7744                 continue;
7745             } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7746                 // caller is same app; don't need to apply any other filtering
7747                 continue;
7748             }
7749             // allow activities that have been explicitly exposed to ephemeral apps
7750             final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7751             if (!isEphemeralApp
7752                     && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7753                 continue;
7754             }
7755             resolveInfos.remove(i);
7756         }
7757         return resolveInfos;
7758     }
7759 
7760     /**
7761      * Returns the activity component that can handle install failures.
7762      * <p>By default, the instant application installer handles failures. However, an
7763      * application may want to handle failures on its own. Applications do this by
7764      * creating an activity with an intent filter that handles the action
7765      * {@link Intent#ACTION_INSTALL_FAILURE}.
7766      */
findInstallFailureActivity( String packageName, int filterCallingUid, int userId)7767     private @Nullable ComponentName findInstallFailureActivity(
7768             String packageName, int filterCallingUid, int userId) {
7769         final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7770         failureActivityIntent.setPackage(packageName);
7771         // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7772         final List<ResolveInfo> result = queryIntentActivitiesInternal(
7773                 failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7774                 false /*resolveForStart*/, false /*allowDynamicSplits*/);
7775         final int NR = result.size();
7776         if (NR > 0) {
7777             for (int i = 0; i < NR; i++) {
7778                 final ResolveInfo info = result.get(i);
7779                 if (info.activityInfo.splitName != null) {
7780                     continue;
7781                 }
7782                 return new ComponentName(packageName, info.activityInfo.name);
7783             }
7784         }
7785         return null;
7786     }
7787 
7788     /**
7789      * @param resolveInfos list of resolve infos in descending priority order
7790      * @return if the list contains a resolve info with non-negative priority
7791      */
hasNonNegativePriority(List<ResolveInfo> resolveInfos)7792     private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7793         return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7794     }
7795 
hasWebURI(Intent intent)7796     private static boolean hasWebURI(Intent intent) {
7797         if (intent.getData() == null) {
7798             return false;
7799         }
7800         final String scheme = intent.getScheme();
7801         if (TextUtils.isEmpty(scheme)) {
7802             return false;
7803         }
7804         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7805     }
7806 
filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int userId)7807     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7808             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7809             int userId) {
7810         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7811 
7812         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7813             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7814                     candidates.size());
7815         }
7816 
7817         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7818         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7819         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7820         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7821         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7822         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7823 
7824         synchronized (mPackages) {
7825             final int count = candidates.size();
7826             // First, try to use linked apps. Partition the candidates into four lists:
7827             // one for the final results, one for the "do not use ever", one for "undefined status"
7828             // and finally one for "browser app type".
7829             for (int n=0; n<count; n++) {
7830                 ResolveInfo info = candidates.get(n);
7831                 String packageName = info.activityInfo.packageName;
7832                 PackageSetting ps = mSettings.mPackages.get(packageName);
7833                 if (ps != null) {
7834                     // Add to the special match all list (Browser use case)
7835                     if (info.handleAllWebDataURI) {
7836                         matchAllList.add(info);
7837                         continue;
7838                     }
7839                     // Try to get the status from User settings first
7840                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7841                     int status = (int)(packedStatus >> 32);
7842                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7843                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7844                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
7845                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7846                                     + " : linkgen=" + linkGeneration);
7847                         }
7848                         // Use link-enabled generation as preferredOrder, i.e.
7849                         // prefer newly-enabled over earlier-enabled.
7850                         info.preferredOrder = linkGeneration;
7851                         alwaysList.add(info);
7852                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7853                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
7854                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7855                         }
7856                         neverList.add(info);
7857                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7858                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
7859                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7860                         }
7861                         alwaysAskList.add(info);
7862                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7863                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7864                         if (DEBUG_DOMAIN_VERIFICATION || debug) {
7865                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7866                         }
7867                         undefinedList.add(info);
7868                     }
7869                 }
7870             }
7871 
7872             // We'll want to include browser possibilities in a few cases
7873             boolean includeBrowser = false;
7874 
7875             // First try to add the "always" resolution(s) for the current user, if any
7876             if (alwaysList.size() > 0) {
7877                 result.addAll(alwaysList);
7878             } else {
7879                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
7880                 result.addAll(undefinedList);
7881                 // Maybe add one for the other profile.
7882                 if (xpDomainInfo != null && (
7883                         xpDomainInfo.bestDomainVerificationStatus
7884                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7885                     result.add(xpDomainInfo.resolveInfo);
7886                 }
7887                 includeBrowser = true;
7888             }
7889 
7890             // The presence of any 'always ask' alternatives means we'll also offer browsers.
7891             // If there were 'always' entries their preferred order has been set, so we also
7892             // back that off to make the alternatives equivalent
7893             if (alwaysAskList.size() > 0) {
7894                 for (ResolveInfo i : result) {
7895                     i.preferredOrder = 0;
7896                 }
7897                 result.addAll(alwaysAskList);
7898                 includeBrowser = true;
7899             }
7900 
7901             if (includeBrowser) {
7902                 // Also add browsers (all of them or only the default one)
7903                 if (DEBUG_DOMAIN_VERIFICATION) {
7904                     Slog.v(TAG, "   ...including browsers in candidate set");
7905                 }
7906                 if ((matchFlags & MATCH_ALL) != 0) {
7907                     result.addAll(matchAllList);
7908                 } else {
7909                     // Browser/generic handling case.  If there's a default browser, go straight
7910                     // to that (but only if there is no other higher-priority match).
7911                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7912                     int maxMatchPrio = 0;
7913                     ResolveInfo defaultBrowserMatch = null;
7914                     final int numCandidates = matchAllList.size();
7915                     for (int n = 0; n < numCandidates; n++) {
7916                         ResolveInfo info = matchAllList.get(n);
7917                         // track the highest overall match priority...
7918                         if (info.priority > maxMatchPrio) {
7919                             maxMatchPrio = info.priority;
7920                         }
7921                         // ...and the highest-priority default browser match
7922                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7923                             if (defaultBrowserMatch == null
7924                                     || (defaultBrowserMatch.priority < info.priority)) {
7925                                 if (debug) {
7926                                     Slog.v(TAG, "Considering default browser match " + info);
7927                                 }
7928                                 defaultBrowserMatch = info;
7929                             }
7930                         }
7931                     }
7932                     if (defaultBrowserMatch != null
7933                             && defaultBrowserMatch.priority >= maxMatchPrio
7934                             && !TextUtils.isEmpty(defaultBrowserPackageName))
7935                     {
7936                         if (debug) {
7937                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7938                         }
7939                         result.add(defaultBrowserMatch);
7940                     } else {
7941                         result.addAll(matchAllList);
7942                     }
7943                 }
7944 
7945                 // If there is nothing selected, add all candidates and remove the ones that the user
7946                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7947                 if (result.size() == 0) {
7948                     result.addAll(candidates);
7949                     result.removeAll(neverList);
7950                 }
7951             }
7952         }
7953         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7954             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7955                     result.size());
7956             for (ResolveInfo info : result) {
7957                 Slog.v(TAG, "  + " + info.activityInfo);
7958             }
7959         }
7960         return result;
7961     }
7962 
7963     // Returns a packed value as a long:
7964     //
7965     // high 'int'-sized word: link status: undefined/ask/never/always.
7966     // low 'int'-sized word: relative priority among 'always' results.
getDomainVerificationStatusLPr(PackageSetting ps, int userId)7967     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7968         long result = ps.getDomainVerificationStatusForUser(userId);
7969         // if none available, get the master status
7970         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7971             if (ps.getIntentFilterVerificationInfo() != null) {
7972                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7973             }
7974         }
7975         return result;
7976     }
7977 
querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)7978     private ResolveInfo querySkipCurrentProfileIntents(
7979             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7980             int flags, int sourceUserId) {
7981         if (matchingFilters != null) {
7982             int size = matchingFilters.size();
7983             for (int i = 0; i < size; i ++) {
7984                 CrossProfileIntentFilter filter = matchingFilters.get(i);
7985                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7986                     // Checking if there are activities in the target user that can handle the
7987                     // intent.
7988                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7989                             resolvedType, flags, sourceUserId);
7990                     if (resolveInfo != null) {
7991                         return resolveInfo;
7992                     }
7993                 }
7994             }
7995         }
7996         return null;
7997     }
7998 
7999     // Return matching ResolveInfo in target user if any.
queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId, boolean matchInCurrentProfile)8000     private ResolveInfo queryCrossProfileIntents(
8001             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
8002             int flags, int sourceUserId, boolean matchInCurrentProfile) {
8003         if (matchingFilters != null) {
8004             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
8005             // match the same intent. For performance reasons, it is better not to
8006             // run queryIntent twice for the same userId
8007             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
8008             int size = matchingFilters.size();
8009             for (int i = 0; i < size; i++) {
8010                 CrossProfileIntentFilter filter = matchingFilters.get(i);
8011                 int targetUserId = filter.getTargetUserId();
8012                 boolean skipCurrentProfile =
8013                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
8014                 boolean skipCurrentProfileIfNoMatchFound =
8015                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
8016                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
8017                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
8018                     // Checking if there are activities in the target user that can handle the
8019                     // intent.
8020                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
8021                             resolvedType, flags, sourceUserId);
8022                     if (resolveInfo != null) return resolveInfo;
8023                     alreadyTriedUserIds.put(targetUserId, true);
8024                 }
8025             }
8026         }
8027         return null;
8028     }
8029 
8030     /**
8031      * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
8032      * will forward the intent to the filter's target user.
8033      * Otherwise, returns null.
8034      */
createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, String resolvedType, int flags, int sourceUserId)8035     private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
8036             String resolvedType, int flags, int sourceUserId) {
8037         int targetUserId = filter.getTargetUserId();
8038         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
8039                 resolvedType, flags, targetUserId);
8040         if (resultTargetUser != null && isUserEnabled(targetUserId)) {
8041             // If all the matches in the target profile are suspended, return null.
8042             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
8043                 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
8044                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
8045                     return createForwardingResolveInfoUnchecked(filter, sourceUserId,
8046                             targetUserId);
8047                 }
8048             }
8049         }
8050         return null;
8051     }
8052 
createForwardingResolveInfoUnchecked(IntentFilter filter, int sourceUserId, int targetUserId)8053     private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
8054             int sourceUserId, int targetUserId) {
8055         ResolveInfo forwardingResolveInfo = new ResolveInfo();
8056         long ident = Binder.clearCallingIdentity();
8057         boolean targetIsProfile;
8058         try {
8059             targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
8060         } finally {
8061             Binder.restoreCallingIdentity(ident);
8062         }
8063         String className;
8064         if (targetIsProfile) {
8065             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
8066         } else {
8067             className = FORWARD_INTENT_TO_PARENT;
8068         }
8069         ComponentName forwardingActivityComponentName = new ComponentName(
8070                 mAndroidApplication.packageName, className);
8071         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
8072                 sourceUserId);
8073         if (!targetIsProfile) {
8074             forwardingActivityInfo.showUserIcon = targetUserId;
8075             forwardingResolveInfo.noResourceId = true;
8076         }
8077         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
8078         forwardingResolveInfo.priority = 0;
8079         forwardingResolveInfo.preferredOrder = 0;
8080         forwardingResolveInfo.match = 0;
8081         forwardingResolveInfo.isDefault = true;
8082         forwardingResolveInfo.filter = filter;
8083         forwardingResolveInfo.targetUserId = targetUserId;
8084         return forwardingResolveInfo;
8085     }
8086 
8087     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)8088     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
8089             Intent[] specifics, String[] specificTypes, Intent intent,
8090             String resolvedType, int flags, int userId) {
8091         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
8092                 specificTypes, intent, resolvedType, flags, userId));
8093     }
8094 
queryIntentActivityOptionsInternal(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)8095     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
8096             Intent[] specifics, String[] specificTypes, Intent intent,
8097             String resolvedType, int flags, int userId) {
8098         if (!sUserManager.exists(userId)) return Collections.emptyList();
8099         final int callingUid = Binder.getCallingUid();
8100         flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8101                 false /*includeInstantApps*/);
8102         enforceCrossUserPermission(callingUid, userId,
8103                 false /*requireFullPermission*/, false /*checkShell*/,
8104                 "query intent activity options");
8105         final String resultsAction = intent.getAction();
8106 
8107         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
8108                 | PackageManager.GET_RESOLVED_FILTER, userId);
8109 
8110         if (DEBUG_INTENT_MATCHING) {
8111             Log.v(TAG, "Query " + intent + ": " + results);
8112         }
8113 
8114         int specificsPos = 0;
8115         int N;
8116 
8117         // todo: note that the algorithm used here is O(N^2).  This
8118         // isn't a problem in our current environment, but if we start running
8119         // into situations where we have more than 5 or 10 matches then this
8120         // should probably be changed to something smarter...
8121 
8122         // First we go through and resolve each of the specific items
8123         // that were supplied, taking care of removing any corresponding
8124         // duplicate items in the generic resolve list.
8125         if (specifics != null) {
8126             for (int i=0; i<specifics.length; i++) {
8127                 final Intent sintent = specifics[i];
8128                 if (sintent == null) {
8129                     continue;
8130                 }
8131 
8132                 if (DEBUG_INTENT_MATCHING) {
8133                     Log.v(TAG, "Specific #" + i + ": " + sintent);
8134                 }
8135 
8136                 String action = sintent.getAction();
8137                 if (resultsAction != null && resultsAction.equals(action)) {
8138                     // If this action was explicitly requested, then don't
8139                     // remove things that have it.
8140                     action = null;
8141                 }
8142 
8143                 ResolveInfo ri = null;
8144                 ActivityInfo ai = null;
8145 
8146                 ComponentName comp = sintent.getComponent();
8147                 if (comp == null) {
8148                     ri = resolveIntent(
8149                         sintent,
8150                         specificTypes != null ? specificTypes[i] : null,
8151                             flags, userId);
8152                     if (ri == null) {
8153                         continue;
8154                     }
8155                     if (ri == mResolveInfo) {
8156                         // ACK!  Must do something better with this.
8157                     }
8158                     ai = ri.activityInfo;
8159                     comp = new ComponentName(ai.applicationInfo.packageName,
8160                             ai.name);
8161                 } else {
8162                     ai = getActivityInfo(comp, flags, userId);
8163                     if (ai == null) {
8164                         continue;
8165                     }
8166                 }
8167 
8168                 // Look for any generic query activities that are duplicates
8169                 // of this specific one, and remove them from the results.
8170                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
8171                 N = results.size();
8172                 int j;
8173                 for (j=specificsPos; j<N; j++) {
8174                     ResolveInfo sri = results.get(j);
8175                     if ((sri.activityInfo.name.equals(comp.getClassName())
8176                             && sri.activityInfo.applicationInfo.packageName.equals(
8177                                     comp.getPackageName()))
8178                         || (action != null && sri.filter.matchAction(action))) {
8179                         results.remove(j);
8180                         if (DEBUG_INTENT_MATCHING) Log.v(
8181                             TAG, "Removing duplicate item from " + j
8182                             + " due to specific " + specificsPos);
8183                         if (ri == null) {
8184                             ri = sri;
8185                         }
8186                         j--;
8187                         N--;
8188                     }
8189                 }
8190 
8191                 // Add this specific item to its proper place.
8192                 if (ri == null) {
8193                     ri = new ResolveInfo();
8194                     ri.activityInfo = ai;
8195                 }
8196                 results.add(specificsPos, ri);
8197                 ri.specificIndex = i;
8198                 specificsPos++;
8199             }
8200         }
8201 
8202         // Now we go through the remaining generic results and remove any
8203         // duplicate actions that are found here.
8204         N = results.size();
8205         for (int i=specificsPos; i<N-1; i++) {
8206             final ResolveInfo rii = results.get(i);
8207             if (rii.filter == null) {
8208                 continue;
8209             }
8210 
8211             // Iterate over all of the actions of this result's intent
8212             // filter...  typically this should be just one.
8213             final Iterator<String> it = rii.filter.actionsIterator();
8214             if (it == null) {
8215                 continue;
8216             }
8217             while (it.hasNext()) {
8218                 final String action = it.next();
8219                 if (resultsAction != null && resultsAction.equals(action)) {
8220                     // If this action was explicitly requested, then don't
8221                     // remove things that have it.
8222                     continue;
8223                 }
8224                 for (int j=i+1; j<N; j++) {
8225                     final ResolveInfo rij = results.get(j);
8226                     if (rij.filter != null && rij.filter.hasAction(action)) {
8227                         results.remove(j);
8228                         if (DEBUG_INTENT_MATCHING) Log.v(
8229                             TAG, "Removing duplicate item from " + j
8230                             + " due to action " + action + " at " + i);
8231                         j--;
8232                         N--;
8233                     }
8234                 }
8235             }
8236 
8237             // If the caller didn't request filter information, drop it now
8238             // so we don't have to marshall/unmarshall it.
8239             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8240                 rii.filter = null;
8241             }
8242         }
8243 
8244         // Filter out the caller activity if so requested.
8245         if (caller != null) {
8246             N = results.size();
8247             for (int i=0; i<N; i++) {
8248                 ActivityInfo ainfo = results.get(i).activityInfo;
8249                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
8250                         && caller.getClassName().equals(ainfo.name)) {
8251                     results.remove(i);
8252                     break;
8253                 }
8254             }
8255         }
8256 
8257         // If the caller didn't request filter information,
8258         // drop them now so we don't have to
8259         // marshall/unmarshall it.
8260         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8261             N = results.size();
8262             for (int i=0; i<N; i++) {
8263                 results.get(i).filter = null;
8264             }
8265         }
8266 
8267         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
8268         return results;
8269     }
8270 
8271     @Override
queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)8272     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
8273             String resolvedType, int flags, int userId) {
8274         return new ParceledListSlice<>(
8275                 queryIntentReceiversInternal(intent, resolvedType, flags, userId,
8276                         false /*allowDynamicSplits*/));
8277     }
8278 
queryIntentReceiversInternal(Intent intent, String resolvedType, int flags, int userId, boolean allowDynamicSplits)8279     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
8280             String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
8281         if (!sUserManager.exists(userId)) return Collections.emptyList();
8282         final int callingUid = Binder.getCallingUid();
8283         enforceCrossUserPermission(callingUid, userId,
8284                 false /*requireFullPermission*/, false /*checkShell*/,
8285                 "query intent receivers");
8286         final String instantAppPkgName = getInstantAppPackageName(callingUid);
8287         flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8288                 false /*includeInstantApps*/);
8289         ComponentName comp = intent.getComponent();
8290         if (comp == null) {
8291             if (intent.getSelector() != null) {
8292                 intent = intent.getSelector();
8293                 comp = intent.getComponent();
8294             }
8295         }
8296         if (comp != null) {
8297             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8298             final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8299             if (ai != null) {
8300                 // When specifying an explicit component, we prevent the activity from being
8301                 // used when either 1) the calling package is normal and the activity is within
8302                 // an instant application or 2) the calling package is ephemeral and the
8303                 // activity is not visible to instant applications.
8304                 final boolean matchInstantApp =
8305                         (flags & PackageManager.MATCH_INSTANT) != 0;
8306                 final boolean matchVisibleToInstantAppOnly =
8307                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8308                 final boolean matchExplicitlyVisibleOnly =
8309                         (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8310                 final boolean isCallerInstantApp =
8311                         instantAppPkgName != null;
8312                 final boolean isTargetSameInstantApp =
8313                         comp.getPackageName().equals(instantAppPkgName);
8314                 final boolean isTargetInstantApp =
8315                         (ai.applicationInfo.privateFlags
8316                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8317                 final boolean isTargetVisibleToInstantApp =
8318                         (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8319                 final boolean isTargetExplicitlyVisibleToInstantApp =
8320                         isTargetVisibleToInstantApp
8321                         && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8322                 final boolean isTargetHiddenFromInstantApp =
8323                         !isTargetVisibleToInstantApp
8324                         || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8325                 final boolean blockResolution =
8326                         !isTargetSameInstantApp
8327                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8328                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8329                                         && isTargetHiddenFromInstantApp));
8330                 if (!blockResolution) {
8331                     ResolveInfo ri = new ResolveInfo();
8332                     ri.activityInfo = ai;
8333                     list.add(ri);
8334                 }
8335             }
8336             return applyPostResolutionFilter(
8337                     list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8338         }
8339 
8340         // reader
8341         synchronized (mPackages) {
8342             String pkgName = intent.getPackage();
8343             if (pkgName == null) {
8344                 final List<ResolveInfo> result =
8345                         mReceivers.queryIntent(intent, resolvedType, flags, userId);
8346                 return applyPostResolutionFilter(
8347                         result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8348             }
8349             final PackageParser.Package pkg = mPackages.get(pkgName);
8350             if (pkg != null) {
8351                 final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
8352                         intent, resolvedType, flags, pkg.receivers, userId);
8353                 return applyPostResolutionFilter(
8354                         result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8355             }
8356             return Collections.emptyList();
8357         }
8358     }
8359 
8360     @Override
resolveService(Intent intent, String resolvedType, int flags, int userId)8361     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8362         final int callingUid = Binder.getCallingUid();
8363         return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8364     }
8365 
resolveServiceInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid)8366     private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8367             int userId, int callingUid) {
8368         if (!sUserManager.exists(userId)) return null;
8369         flags = updateFlagsForResolve(
8370                 flags, userId, intent, callingUid, false /*includeInstantApps*/);
8371         List<ResolveInfo> query = queryIntentServicesInternal(
8372                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8373         if (query != null) {
8374             if (query.size() >= 1) {
8375                 // If there is more than one service with the same priority,
8376                 // just arbitrarily pick the first one.
8377                 return query.get(0);
8378             }
8379         }
8380         return null;
8381     }
8382 
8383     @Override
queryIntentServices(Intent intent, String resolvedType, int flags, int userId)8384     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8385             String resolvedType, int flags, int userId) {
8386         final int callingUid = Binder.getCallingUid();
8387         return new ParceledListSlice<>(queryIntentServicesInternal(
8388                 intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8389     }
8390 
queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId, int callingUid, boolean includeInstantApps)8391     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8392             String resolvedType, int flags, int userId, int callingUid,
8393             boolean includeInstantApps) {
8394         if (!sUserManager.exists(userId)) return Collections.emptyList();
8395         enforceCrossUserPermission(callingUid, userId,
8396                 false /*requireFullPermission*/, false /*checkShell*/,
8397                 "query intent receivers");
8398         final String instantAppPkgName = getInstantAppPackageName(callingUid);
8399         flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8400         ComponentName comp = intent.getComponent();
8401         if (comp == null) {
8402             if (intent.getSelector() != null) {
8403                 intent = intent.getSelector();
8404                 comp = intent.getComponent();
8405             }
8406         }
8407         if (comp != null) {
8408             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8409             final ServiceInfo si = getServiceInfo(comp, flags, userId);
8410             if (si != null) {
8411                 // When specifying an explicit component, we prevent the service from being
8412                 // used when either 1) the service is in an instant application and the
8413                 // caller is not the same instant application or 2) the calling package is
8414                 // ephemeral and the activity is not visible to ephemeral applications.
8415                 final boolean matchInstantApp =
8416                         (flags & PackageManager.MATCH_INSTANT) != 0;
8417                 final boolean matchVisibleToInstantAppOnly =
8418                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8419                 final boolean isCallerInstantApp =
8420                         instantAppPkgName != null;
8421                 final boolean isTargetSameInstantApp =
8422                         comp.getPackageName().equals(instantAppPkgName);
8423                 final boolean isTargetInstantApp =
8424                         (si.applicationInfo.privateFlags
8425                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8426                 final boolean isTargetHiddenFromInstantApp =
8427                         (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8428                 final boolean blockResolution =
8429                         !isTargetSameInstantApp
8430                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8431                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8432                                         && isTargetHiddenFromInstantApp));
8433                 if (!blockResolution) {
8434                     final ResolveInfo ri = new ResolveInfo();
8435                     ri.serviceInfo = si;
8436                     list.add(ri);
8437                 }
8438             }
8439             return list;
8440         }
8441 
8442         // reader
8443         synchronized (mPackages) {
8444             String pkgName = intent.getPackage();
8445             if (pkgName == null) {
8446                 return applyPostServiceResolutionFilter(
8447                         mServices.queryIntent(intent, resolvedType, flags, userId),
8448                         instantAppPkgName);
8449             }
8450             final PackageParser.Package pkg = mPackages.get(pkgName);
8451             if (pkg != null) {
8452                 return applyPostServiceResolutionFilter(
8453                         mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
8454                                 userId),
8455                         instantAppPkgName);
8456             }
8457             return Collections.emptyList();
8458         }
8459     }
8460 
applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos, String instantAppPkgName)8461     private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8462             String instantAppPkgName) {
8463         if (instantAppPkgName == null) {
8464             return resolveInfos;
8465         }
8466         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8467             final ResolveInfo info = resolveInfos.get(i);
8468             final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8469             // allow services that are defined in the provided package
8470             if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8471                 if (info.serviceInfo.splitName != null
8472                         && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8473                                 info.serviceInfo.splitName)) {
8474                     // requested service is defined in a split that hasn't been installed yet.
8475                     // add the installer to the resolve list
8476                     if (DEBUG_EPHEMERAL) {
8477                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8478                     }
8479                     final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8480                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8481                             info.serviceInfo.packageName, info.serviceInfo.splitName,
8482                             null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
8483                             null /*failureIntent*/);
8484                     // make sure this resolver is the default
8485                     installerInfo.isDefault = true;
8486                     installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8487                             | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8488                     // add a non-generic filter
8489                     installerInfo.filter = new IntentFilter();
8490                     // load resources from the correct package
8491                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8492                     resolveInfos.set(i, installerInfo);
8493                 }
8494                 continue;
8495             }
8496             // allow services that have been explicitly exposed to ephemeral apps
8497             if (!isEphemeralApp
8498                     && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8499                 continue;
8500             }
8501             resolveInfos.remove(i);
8502         }
8503         return resolveInfos;
8504     }
8505 
8506     @Override
queryIntentContentProviders(Intent intent, String resolvedType, int flags, int userId)8507     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8508             String resolvedType, int flags, int userId) {
8509         return new ParceledListSlice<>(
8510                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8511     }
8512 
queryIntentContentProvidersInternal( Intent intent, String resolvedType, int flags, int userId)8513     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8514             Intent intent, String resolvedType, int flags, int userId) {
8515         if (!sUserManager.exists(userId)) return Collections.emptyList();
8516         final int callingUid = Binder.getCallingUid();
8517         final String instantAppPkgName = getInstantAppPackageName(callingUid);
8518         flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8519                 false /*includeInstantApps*/);
8520         ComponentName comp = intent.getComponent();
8521         if (comp == null) {
8522             if (intent.getSelector() != null) {
8523                 intent = intent.getSelector();
8524                 comp = intent.getComponent();
8525             }
8526         }
8527         if (comp != null) {
8528             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8529             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8530             if (pi != null) {
8531                 // When specifying an explicit component, we prevent the provider from being
8532                 // used when either 1) the provider is in an instant application and the
8533                 // caller is not the same instant application or 2) the calling package is an
8534                 // instant application and the provider is not visible to instant applications.
8535                 final boolean matchInstantApp =
8536                         (flags & PackageManager.MATCH_INSTANT) != 0;
8537                 final boolean matchVisibleToInstantAppOnly =
8538                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8539                 final boolean isCallerInstantApp =
8540                         instantAppPkgName != null;
8541                 final boolean isTargetSameInstantApp =
8542                         comp.getPackageName().equals(instantAppPkgName);
8543                 final boolean isTargetInstantApp =
8544                         (pi.applicationInfo.privateFlags
8545                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8546                 final boolean isTargetHiddenFromInstantApp =
8547                         (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8548                 final boolean blockResolution =
8549                         !isTargetSameInstantApp
8550                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8551                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
8552                                         && isTargetHiddenFromInstantApp));
8553                 if (!blockResolution) {
8554                     final ResolveInfo ri = new ResolveInfo();
8555                     ri.providerInfo = pi;
8556                     list.add(ri);
8557                 }
8558             }
8559             return list;
8560         }
8561 
8562         // reader
8563         synchronized (mPackages) {
8564             String pkgName = intent.getPackage();
8565             if (pkgName == null) {
8566                 return applyPostContentProviderResolutionFilter(
8567                         mProviders.queryIntent(intent, resolvedType, flags, userId),
8568                         instantAppPkgName);
8569             }
8570             final PackageParser.Package pkg = mPackages.get(pkgName);
8571             if (pkg != null) {
8572                 return applyPostContentProviderResolutionFilter(
8573                         mProviders.queryIntentForPackage(
8574                         intent, resolvedType, flags, pkg.providers, userId),
8575                         instantAppPkgName);
8576             }
8577             return Collections.emptyList();
8578         }
8579     }
8580 
applyPostContentProviderResolutionFilter( List<ResolveInfo> resolveInfos, String instantAppPkgName)8581     private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8582             List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8583         if (instantAppPkgName == null) {
8584             return resolveInfos;
8585         }
8586         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8587             final ResolveInfo info = resolveInfos.get(i);
8588             final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8589             // allow providers that are defined in the provided package
8590             if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8591                 if (info.providerInfo.splitName != null
8592                         && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8593                                 info.providerInfo.splitName)) {
8594                     // requested provider is defined in a split that hasn't been installed yet.
8595                     // add the installer to the resolve list
8596                     if (DEBUG_EPHEMERAL) {
8597                         Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8598                     }
8599                     final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8600                     installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8601                             info.providerInfo.packageName, info.providerInfo.splitName,
8602                             null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
8603                             null /*failureIntent*/);
8604                     // make sure this resolver is the default
8605                     installerInfo.isDefault = true;
8606                     installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8607                             | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8608                     // add a non-generic filter
8609                     installerInfo.filter = new IntentFilter();
8610                     // load resources from the correct package
8611                     installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8612                     resolveInfos.set(i, installerInfo);
8613                 }
8614                 continue;
8615             }
8616             // allow providers that have been explicitly exposed to instant applications
8617             if (!isEphemeralApp
8618                     && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8619                 continue;
8620             }
8621             resolveInfos.remove(i);
8622         }
8623         return resolveInfos;
8624     }
8625 
8626     @Override
getInstalledPackages(int flags, int userId)8627     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8628         final int callingUid = Binder.getCallingUid();
8629         if (getInstantAppPackageName(callingUid) != null) {
8630             return ParceledListSlice.emptyList();
8631         }
8632         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8633         flags = updateFlagsForPackage(flags, userId, null);
8634         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8635         enforceCrossUserPermission(callingUid, userId,
8636                 true /* requireFullPermission */, false /* checkShell */,
8637                 "get installed packages");
8638 
8639         // writer
8640         synchronized (mPackages) {
8641             ArrayList<PackageInfo> list;
8642             if (listUninstalled) {
8643                 list = new ArrayList<>(mSettings.mPackages.size());
8644                 for (PackageSetting ps : mSettings.mPackages.values()) {
8645                     if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8646                         continue;
8647                     }
8648                     if (filterAppAccessLPr(ps, callingUid, userId)) {
8649                         continue;
8650                     }
8651                     final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8652                     if (pi != null) {
8653                         list.add(pi);
8654                     }
8655                 }
8656             } else {
8657                 list = new ArrayList<>(mPackages.size());
8658                 for (PackageParser.Package p : mPackages.values()) {
8659                     final PackageSetting ps = (PackageSetting) p.mExtras;
8660                     if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8661                         continue;
8662                     }
8663                     if (filterAppAccessLPr(ps, callingUid, userId)) {
8664                         continue;
8665                     }
8666                     final PackageInfo pi = generatePackageInfo((PackageSetting)
8667                             p.mExtras, flags, userId);
8668                     if (pi != null) {
8669                         list.add(pi);
8670                     }
8671                 }
8672             }
8673 
8674             return new ParceledListSlice<>(list);
8675         }
8676     }
8677 
addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)8678     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8679             String[] permissions, boolean[] tmp, int flags, int userId) {
8680         int numMatch = 0;
8681         final PermissionsState permissionsState = ps.getPermissionsState();
8682         for (int i=0; i<permissions.length; i++) {
8683             final String permission = permissions[i];
8684             if (permissionsState.hasPermission(permission, userId)) {
8685                 tmp[i] = true;
8686                 numMatch++;
8687             } else {
8688                 tmp[i] = false;
8689             }
8690         }
8691         if (numMatch == 0) {
8692             return;
8693         }
8694         final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8695 
8696         // The above might return null in cases of uninstalled apps or install-state
8697         // skew across users/profiles.
8698         if (pi != null) {
8699             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8700                 if (numMatch == permissions.length) {
8701                     pi.requestedPermissions = permissions;
8702                 } else {
8703                     pi.requestedPermissions = new String[numMatch];
8704                     numMatch = 0;
8705                     for (int i=0; i<permissions.length; i++) {
8706                         if (tmp[i]) {
8707                             pi.requestedPermissions[numMatch] = permissions[i];
8708                             numMatch++;
8709                         }
8710                     }
8711                 }
8712             }
8713             list.add(pi);
8714         }
8715     }
8716 
8717     @Override
getPackagesHoldingPermissions( String[] permissions, int flags, int userId)8718     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8719             String[] permissions, int flags, int userId) {
8720         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8721         flags = updateFlagsForPackage(flags, userId, permissions);
8722         enforceCrossUserPermission(Binder.getCallingUid(), userId,
8723                 true /* requireFullPermission */, false /* checkShell */,
8724                 "get packages holding permissions");
8725         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8726 
8727         // writer
8728         synchronized (mPackages) {
8729             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8730             boolean[] tmpBools = new boolean[permissions.length];
8731             if (listUninstalled) {
8732                 for (PackageSetting ps : mSettings.mPackages.values()) {
8733                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8734                             userId);
8735                 }
8736             } else {
8737                 for (PackageParser.Package pkg : mPackages.values()) {
8738                     PackageSetting ps = (PackageSetting)pkg.mExtras;
8739                     if (ps != null) {
8740                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8741                                 userId);
8742                     }
8743                 }
8744             }
8745 
8746             return new ParceledListSlice<PackageInfo>(list);
8747         }
8748     }
8749 
8750     @Override
getInstalledApplications(int flags, int userId)8751     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8752         final int callingUid = Binder.getCallingUid();
8753         if (getInstantAppPackageName(callingUid) != null) {
8754             return ParceledListSlice.emptyList();
8755         }
8756         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8757         flags = updateFlagsForApplication(flags, userId, null);
8758         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8759 
8760         // writer
8761         synchronized (mPackages) {
8762             ArrayList<ApplicationInfo> list;
8763             if (listUninstalled) {
8764                 list = new ArrayList<>(mSettings.mPackages.size());
8765                 for (PackageSetting ps : mSettings.mPackages.values()) {
8766                     ApplicationInfo ai;
8767                     int effectiveFlags = flags;
8768                     if (ps.isSystem()) {
8769                         effectiveFlags |= PackageManager.MATCH_ANY_USER;
8770                     }
8771                     if (ps.pkg != null) {
8772                         if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8773                             continue;
8774                         }
8775                         if (filterAppAccessLPr(ps, callingUid, userId)) {
8776                             continue;
8777                         }
8778                         ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8779                                 ps.readUserState(userId), userId);
8780                         if (ai != null) {
8781                             ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8782                         }
8783                     } else {
8784                         // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8785                         // and already converts to externally visible package name
8786                         ai = generateApplicationInfoFromSettingsLPw(ps.name,
8787                                 callingUid, effectiveFlags, userId);
8788                     }
8789                     if (ai != null) {
8790                         list.add(ai);
8791                     }
8792                 }
8793             } else {
8794                 list = new ArrayList<>(mPackages.size());
8795                 for (PackageParser.Package p : mPackages.values()) {
8796                     if (p.mExtras != null) {
8797                         PackageSetting ps = (PackageSetting) p.mExtras;
8798                         if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8799                             continue;
8800                         }
8801                         if (filterAppAccessLPr(ps, callingUid, userId)) {
8802                             continue;
8803                         }
8804                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8805                                 ps.readUserState(userId), userId);
8806                         if (ai != null) {
8807                             ai.packageName = resolveExternalPackageNameLPr(p);
8808                             list.add(ai);
8809                         }
8810                     }
8811                 }
8812             }
8813 
8814             return new ParceledListSlice<>(list);
8815         }
8816     }
8817 
8818     @Override
getInstantApps(int userId)8819     public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8820         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8821             return null;
8822         }
8823         if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8824             mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8825                     "getEphemeralApplications");
8826         }
8827         enforceCrossUserPermission(Binder.getCallingUid(), userId,
8828                 true /* requireFullPermission */, false /* checkShell */,
8829                 "getEphemeralApplications");
8830         synchronized (mPackages) {
8831             List<InstantAppInfo> instantApps = mInstantAppRegistry
8832                     .getInstantAppsLPr(userId);
8833             if (instantApps != null) {
8834                 return new ParceledListSlice<>(instantApps);
8835             }
8836         }
8837         return null;
8838     }
8839 
8840     @Override
isInstantApp(String packageName, int userId)8841     public boolean isInstantApp(String packageName, int userId) {
8842         enforceCrossUserPermission(Binder.getCallingUid(), userId,
8843                 true /* requireFullPermission */, false /* checkShell */,
8844                 "isInstantApp");
8845         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8846             return false;
8847         }
8848 
8849         synchronized (mPackages) {
8850             int callingUid = Binder.getCallingUid();
8851             if (Process.isIsolated(callingUid)) {
8852                 callingUid = mIsolatedOwners.get(callingUid);
8853             }
8854             final PackageSetting ps = mSettings.mPackages.get(packageName);
8855             PackageParser.Package pkg = mPackages.get(packageName);
8856             final boolean returnAllowed =
8857                     ps != null
8858                     && (isCallerSameApp(packageName, callingUid)
8859                             || canViewInstantApps(callingUid, userId)
8860                             || mInstantAppRegistry.isInstantAccessGranted(
8861                                     userId, UserHandle.getAppId(callingUid), ps.appId));
8862             if (returnAllowed) {
8863                 return ps.getInstantApp(userId);
8864             }
8865         }
8866         return false;
8867     }
8868 
8869     @Override
getInstantAppCookie(String packageName, int userId)8870     public byte[] getInstantAppCookie(String packageName, int userId) {
8871         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8872             return null;
8873         }
8874 
8875         enforceCrossUserPermission(Binder.getCallingUid(), userId,
8876                 true /* requireFullPermission */, false /* checkShell */,
8877                 "getInstantAppCookie");
8878         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8879             return null;
8880         }
8881         synchronized (mPackages) {
8882             return mInstantAppRegistry.getInstantAppCookieLPw(
8883                     packageName, userId);
8884         }
8885     }
8886 
8887     @Override
setInstantAppCookie(String packageName, byte[] cookie, int userId)8888     public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8889         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8890             return true;
8891         }
8892 
8893         enforceCrossUserPermission(Binder.getCallingUid(), userId,
8894                 true /* requireFullPermission */, true /* checkShell */,
8895                 "setInstantAppCookie");
8896         if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8897             return false;
8898         }
8899         synchronized (mPackages) {
8900             return mInstantAppRegistry.setInstantAppCookieLPw(
8901                     packageName, cookie, userId);
8902         }
8903     }
8904 
8905     @Override
getInstantAppIcon(String packageName, int userId)8906     public Bitmap getInstantAppIcon(String packageName, int userId) {
8907         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8908             return null;
8909         }
8910 
8911         if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8912             mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8913                     "getInstantAppIcon");
8914         }
8915         enforceCrossUserPermission(Binder.getCallingUid(), userId,
8916                 true /* requireFullPermission */, false /* checkShell */,
8917                 "getInstantAppIcon");
8918 
8919         synchronized (mPackages) {
8920             return mInstantAppRegistry.getInstantAppIconLPw(
8921                     packageName, userId);
8922         }
8923     }
8924 
isCallerSameApp(String packageName, int uid)8925     private boolean isCallerSameApp(String packageName, int uid) {
8926         PackageParser.Package pkg = mPackages.get(packageName);
8927         return pkg != null
8928                 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8929     }
8930 
8931     @Override
getPersistentApplications(int flags)8932     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8933         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8934             return ParceledListSlice.emptyList();
8935         }
8936         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8937     }
8938 
getPersistentApplicationsInternal(int flags)8939     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8940         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8941 
8942         // reader
8943         synchronized (mPackages) {
8944             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8945             final int userId = UserHandle.getCallingUserId();
8946             while (i.hasNext()) {
8947                 final PackageParser.Package p = i.next();
8948                 if (p.applicationInfo == null) continue;
8949 
8950                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8951                         && !p.applicationInfo.isDirectBootAware();
8952                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8953                         && p.applicationInfo.isDirectBootAware();
8954 
8955                 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8956                         && (!mSafeMode || isSystemApp(p))
8957                         && (matchesUnaware || matchesAware)) {
8958                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
8959                     if (ps != null) {
8960                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8961                                 ps.readUserState(userId), userId);
8962                         if (ai != null) {
8963                             finalList.add(ai);
8964                         }
8965                     }
8966                 }
8967             }
8968         }
8969 
8970         return finalList;
8971     }
8972 
8973     @Override
resolveContentProvider(String name, int flags, int userId)8974     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8975         if (!sUserManager.exists(userId)) return null;
8976         flags = updateFlagsForComponent(flags, userId, name);
8977         final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8978         // reader
8979         synchronized (mPackages) {
8980             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8981             PackageSetting ps = provider != null
8982                     ? mSettings.mPackages.get(provider.owner.packageName)
8983                     : null;
8984             if (ps != null) {
8985                 final boolean isInstantApp = ps.getInstantApp(userId);
8986                 // normal application; filter out instant application provider
8987                 if (instantAppPkgName == null && isInstantApp) {
8988                     return null;
8989                 }
8990                 // instant application; filter out other instant applications
8991                 if (instantAppPkgName != null
8992                         && isInstantApp
8993                         && !provider.owner.packageName.equals(instantAppPkgName)) {
8994                     return null;
8995                 }
8996                 // instant application; filter out non-exposed provider
8997                 if (instantAppPkgName != null
8998                         && !isInstantApp
8999                         && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
9000                     return null;
9001                 }
9002                 // provider not enabled
9003                 if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
9004                     return null;
9005                 }
9006                 return PackageParser.generateProviderInfo(
9007                         provider, flags, ps.readUserState(userId), userId);
9008             }
9009             return null;
9010         }
9011     }
9012 
9013     /**
9014      * @deprecated
9015      */
9016     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)9017     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
9018         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9019             return;
9020         }
9021         // reader
9022         synchronized (mPackages) {
9023             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
9024                     .entrySet().iterator();
9025             final int userId = UserHandle.getCallingUserId();
9026             while (i.hasNext()) {
9027                 Map.Entry<String, PackageParser.Provider> entry = i.next();
9028                 PackageParser.Provider p = entry.getValue();
9029                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
9030 
9031                 if (ps != null && p.syncable
9032                         && (!mSafeMode || (p.info.applicationInfo.flags
9033                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
9034                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
9035                             ps.readUserState(userId), userId);
9036                     if (info != null) {
9037                         outNames.add(entry.getKey());
9038                         outInfo.add(info);
9039                     }
9040                 }
9041             }
9042         }
9043     }
9044 
9045     @Override
queryContentProviders(String processName, int uid, int flags, String metaDataKey)9046     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
9047             int uid, int flags, String metaDataKey) {
9048         final int callingUid = Binder.getCallingUid();
9049         final int userId = processName != null ? UserHandle.getUserId(uid)
9050                 : UserHandle.getCallingUserId();
9051         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
9052         flags = updateFlagsForComponent(flags, userId, processName);
9053         ArrayList<ProviderInfo> finalList = null;
9054         // reader
9055         synchronized (mPackages) {
9056             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
9057             while (i.hasNext()) {
9058                 final PackageParser.Provider p = i.next();
9059                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
9060                 if (ps != null && p.info.authority != null
9061                         && (processName == null
9062                                 || (p.info.processName.equals(processName)
9063                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
9064                         && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
9065 
9066                     // See PM.queryContentProviders()'s javadoc for why we have the metaData
9067                     // parameter.
9068                     if (metaDataKey != null
9069                             && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
9070                         continue;
9071                     }
9072                     final ComponentName component =
9073                             new ComponentName(p.info.packageName, p.info.name);
9074                     if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
9075                         continue;
9076                     }
9077                     if (finalList == null) {
9078                         finalList = new ArrayList<ProviderInfo>(3);
9079                     }
9080                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
9081                             ps.readUserState(userId), userId);
9082                     if (info != null) {
9083                         finalList.add(info);
9084                     }
9085                 }
9086             }
9087         }
9088 
9089         if (finalList != null) {
9090             Collections.sort(finalList, mProviderInitOrderSorter);
9091             return new ParceledListSlice<ProviderInfo>(finalList);
9092         }
9093 
9094         return ParceledListSlice.emptyList();
9095     }
9096 
9097     @Override
getInstrumentationInfo(ComponentName component, int flags)9098     public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
9099         // reader
9100         synchronized (mPackages) {
9101             final int callingUid = Binder.getCallingUid();
9102             final int callingUserId = UserHandle.getUserId(callingUid);
9103             final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
9104             if (ps == null) return null;
9105             if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
9106                 return null;
9107             }
9108             final PackageParser.Instrumentation i = mInstrumentation.get(component);
9109             return PackageParser.generateInstrumentationInfo(i, flags);
9110         }
9111     }
9112 
9113     @Override
queryInstrumentation( String targetPackage, int flags)9114     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
9115             String targetPackage, int flags) {
9116         final int callingUid = Binder.getCallingUid();
9117         final int callingUserId = UserHandle.getUserId(callingUid);
9118         final PackageSetting ps = mSettings.mPackages.get(targetPackage);
9119         if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
9120             return ParceledListSlice.emptyList();
9121         }
9122         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
9123     }
9124 
queryInstrumentationInternal(String targetPackage, int flags)9125     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
9126             int flags) {
9127         ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
9128 
9129         // reader
9130         synchronized (mPackages) {
9131             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
9132             while (i.hasNext()) {
9133                 final PackageParser.Instrumentation p = i.next();
9134                 if (targetPackage == null
9135                         || targetPackage.equals(p.info.targetPackage)) {
9136                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
9137                             flags);
9138                     if (ii != null) {
9139                         finalList.add(ii);
9140                     }
9141                 }
9142             }
9143         }
9144 
9145         return finalList;
9146     }
9147 
scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime)9148     private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
9149         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
9150         try {
9151             scanDirLI(dir, parseFlags, scanFlags, currentTime);
9152         } finally {
9153             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9154         }
9155     }
9156 
scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime)9157     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
9158         final File[] files = dir.listFiles();
9159         if (ArrayUtils.isEmpty(files)) {
9160             Log.d(TAG, "No files in app dir " + dir);
9161             return;
9162         }
9163 
9164         if (DEBUG_PACKAGE_SCANNING) {
9165             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
9166                     + " flags=0x" + Integer.toHexString(parseFlags));
9167         }
9168         ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
9169                 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
9170                 mParallelPackageParserCallback);
9171 
9172         // Submit files for parsing in parallel
9173         int fileCount = 0;
9174         for (File file : files) {
9175             final boolean isPackage = (isApkFile(file) || file.isDirectory())
9176                     && !PackageInstallerService.isStageName(file.getName());
9177             if (!isPackage) {
9178                 // Ignore entries which are not packages
9179                 continue;
9180             }
9181             parallelPackageParser.submit(file, parseFlags);
9182             fileCount++;
9183         }
9184 
9185         // Process results one by one
9186         for (; fileCount > 0; fileCount--) {
9187             ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
9188             Throwable throwable = parseResult.throwable;
9189             int errorCode = PackageManager.INSTALL_SUCCEEDED;
9190 
9191             if (throwable == null) {
9192                 // Static shared libraries have synthetic package names
9193                 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
9194                     renameStaticSharedLibraryPackage(parseResult.pkg);
9195                 }
9196                 try {
9197                     if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
9198                         scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
9199                                 currentTime, null);
9200                     }
9201                 } catch (PackageManagerException e) {
9202                     errorCode = e.error;
9203                     Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
9204                 }
9205             } else if (throwable instanceof PackageParser.PackageParserException) {
9206                 PackageParser.PackageParserException e = (PackageParser.PackageParserException)
9207                         throwable;
9208                 errorCode = e.error;
9209                 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
9210             } else {
9211                 throw new IllegalStateException("Unexpected exception occurred while parsing "
9212                         + parseResult.scanFile, throwable);
9213             }
9214 
9215             // Delete invalid userdata apps
9216             if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
9217                     errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
9218                 logCriticalInfo(Log.WARN,
9219                         "Deleting invalid package at " + parseResult.scanFile);
9220                 removeCodePathLI(parseResult.scanFile);
9221             }
9222         }
9223         parallelPackageParser.close();
9224     }
9225 
getSettingsProblemFile()9226     private static File getSettingsProblemFile() {
9227         File dataDir = Environment.getDataDirectory();
9228         File systemDir = new File(dataDir, "system");
9229         File fname = new File(systemDir, "uiderrors.txt");
9230         return fname;
9231     }
9232 
reportSettingsProblem(int priority, String msg)9233     static void reportSettingsProblem(int priority, String msg) {
9234         logCriticalInfo(priority, msg);
9235     }
9236 
logCriticalInfo(int priority, String msg)9237     public static void logCriticalInfo(int priority, String msg) {
9238         Slog.println(priority, TAG, msg);
9239         EventLogTags.writePmCriticalInfo(msg);
9240         try {
9241             File fname = getSettingsProblemFile();
9242             FileOutputStream out = new FileOutputStream(fname, true);
9243             PrintWriter pw = new FastPrintWriter(out);
9244             SimpleDateFormat formatter = new SimpleDateFormat();
9245             String dateString = formatter.format(new Date(System.currentTimeMillis()));
9246             pw.println(dateString + ": " + msg);
9247             pw.close();
9248             FileUtils.setPermissions(
9249                     fname.toString(),
9250                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
9251                     -1, -1);
9252         } catch (java.io.IOException e) {
9253         }
9254     }
9255 
getLastModifiedTime(PackageParser.Package pkg, File srcFile)9256     private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
9257         if (srcFile.isDirectory()) {
9258             final File baseFile = new File(pkg.baseCodePath);
9259             long maxModifiedTime = baseFile.lastModified();
9260             if (pkg.splitCodePaths != null) {
9261                 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
9262                     final File splitFile = new File(pkg.splitCodePaths[i]);
9263                     maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
9264                 }
9265             }
9266             return maxModifiedTime;
9267         }
9268         return srcFile.lastModified();
9269     }
9270 
collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, final int policyFlags)9271     private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
9272             final int policyFlags) throws PackageManagerException {
9273         // When upgrading from pre-N MR1, verify the package time stamp using the package
9274         // directory and not the APK file.
9275         final long lastModifiedTime = mIsPreNMR1Upgrade
9276                 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
9277         if (ps != null
9278                 && ps.codePath.equals(srcFile)
9279                 && ps.timeStamp == lastModifiedTime
9280                 && !isCompatSignatureUpdateNeeded(pkg)
9281                 && !isRecoverSignatureUpdateNeeded(pkg)) {
9282             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
9283             KeySetManagerService ksms = mSettings.mKeySetManagerService;
9284             ArraySet<PublicKey> signingKs;
9285             synchronized (mPackages) {
9286                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
9287             }
9288             if (ps.signatures.mSignatures != null
9289                     && ps.signatures.mSignatures.length != 0
9290                     && signingKs != null) {
9291                 // Optimization: reuse the existing cached certificates
9292                 // if the package appears to be unchanged.
9293                 pkg.mSignatures = ps.signatures.mSignatures;
9294                 pkg.mSigningKeys = signingKs;
9295                 return;
9296             }
9297 
9298             Slog.w(TAG, "PackageSetting for " + ps.name
9299                     + " is missing signatures.  Collecting certs again to recover them.");
9300         } else {
9301             Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
9302         }
9303 
9304         try {
9305             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9306             PackageParser.collectCertificates(pkg, policyFlags);
9307         } catch (PackageParserException e) {
9308             throw PackageManagerException.from(e);
9309         } finally {
9310             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9311         }
9312     }
9313 
9314     /**
9315      *  Traces a package scan.
9316      *  @see #scanPackageLI(File, int, int, long, UserHandle)
9317      */
scanPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, long currentTime, UserHandle user)9318     private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9319             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9320         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9321         try {
9322             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9323         } finally {
9324             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9325         }
9326     }
9327 
9328     /**
9329      *  Scans a package and returns the newly parsed package.
9330      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
9331      */
scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)9332     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9333             long currentTime, UserHandle user) throws PackageManagerException {
9334         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9335         PackageParser pp = new PackageParser();
9336         pp.setSeparateProcesses(mSeparateProcesses);
9337         pp.setOnlyCoreApps(mOnlyCore);
9338         pp.setDisplayMetrics(mMetrics);
9339         pp.setCallback(mPackageParserCallback);
9340 
9341         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
9342             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
9343         }
9344 
9345         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9346         final PackageParser.Package pkg;
9347         try {
9348             pkg = pp.parsePackage(scanFile, parseFlags);
9349         } catch (PackageParserException e) {
9350             throw PackageManagerException.from(e);
9351         } finally {
9352             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9353         }
9354 
9355         // Static shared libraries have synthetic package names
9356         if (pkg.applicationInfo.isStaticSharedLibrary()) {
9357             renameStaticSharedLibraryPackage(pkg);
9358         }
9359 
9360         return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
9361     }
9362 
9363     /**
9364      *  Scans a package and returns the newly parsed package.
9365      *  @throws PackageManagerException on a parse error.
9366      */
scanPackageLI(PackageParser.Package pkg, File scanFile, final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)9367     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
9368             final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9369             throws PackageManagerException {
9370         // If the package has children and this is the first dive in the function
9371         // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9372         // packages (parent and children) would be successfully scanned before the
9373         // actual scan since scanning mutates internal state and we want to atomically
9374         // install the package and its children.
9375         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9376             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9377                 scanFlags |= SCAN_CHECK_ONLY;
9378             }
9379         } else {
9380             scanFlags &= ~SCAN_CHECK_ONLY;
9381         }
9382 
9383         // Scan the parent
9384         PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
9385                 scanFlags, currentTime, user);
9386 
9387         // Scan the children
9388         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9389         for (int i = 0; i < childCount; i++) {
9390             PackageParser.Package childPackage = pkg.childPackages.get(i);
9391             scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
9392                     currentTime, user);
9393         }
9394 
9395 
9396         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9397             return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
9398         }
9399 
9400         return scannedPkg;
9401     }
9402 
9403     /**
9404      *  Scans a package and returns the newly parsed package.
9405      *  @throws PackageManagerException on a parse error.
9406      */
scanPackageInternalLI(PackageParser.Package pkg, File scanFile, int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)9407     private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
9408             int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9409             throws PackageManagerException {
9410         PackageSetting ps = null;
9411         PackageSetting updatedPkg;
9412         // reader
9413         synchronized (mPackages) {
9414             // Look to see if we already know about this package.
9415             String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
9416             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
9417                 // This package has been renamed to its original name.  Let's
9418                 // use that.
9419                 ps = mSettings.getPackageLPr(oldName);
9420             }
9421             // If there was no original package, see one for the real package name.
9422             if (ps == null) {
9423                 ps = mSettings.getPackageLPr(pkg.packageName);
9424             }
9425             // Check to see if this package could be hiding/updating a system
9426             // package.  Must look for it either under the original or real
9427             // package name depending on our state.
9428             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
9429             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
9430 
9431             // If this is a package we don't know about on the system partition, we
9432             // may need to remove disabled child packages on the system partition
9433             // or may need to not add child packages if the parent apk is updated
9434             // on the data partition and no longer defines this child package.
9435             if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
9436                 // If this is a parent package for an updated system app and this system
9437                 // app got an OTA update which no longer defines some of the child packages
9438                 // we have to prune them from the disabled system packages.
9439                 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9440                 if (disabledPs != null) {
9441                     final int scannedChildCount = (pkg.childPackages != null)
9442                             ? pkg.childPackages.size() : 0;
9443                     final int disabledChildCount = disabledPs.childPackageNames != null
9444                             ? disabledPs.childPackageNames.size() : 0;
9445                     for (int i = 0; i < disabledChildCount; i++) {
9446                         String disabledChildPackageName = disabledPs.childPackageNames.get(i);
9447                         boolean disabledPackageAvailable = false;
9448                         for (int j = 0; j < scannedChildCount; j++) {
9449                             PackageParser.Package childPkg = pkg.childPackages.get(j);
9450                             if (childPkg.packageName.equals(disabledChildPackageName)) {
9451                                 disabledPackageAvailable = true;
9452                                 break;
9453                             }
9454                          }
9455                          if (!disabledPackageAvailable) {
9456                              mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9457                          }
9458                     }
9459                 }
9460             }
9461         }
9462 
9463         final boolean isUpdatedPkg = updatedPkg != null;
9464         final boolean isUpdatedSystemPkg = isUpdatedPkg
9465                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
9466         boolean isUpdatedPkgBetter = false;
9467         // First check if this is a system package that may involve an update
9468         if (isUpdatedSystemPkg) {
9469             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
9470             // it needs to drop FLAG_PRIVILEGED.
9471             if (locationIsPrivileged(scanFile)) {
9472                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9473             } else {
9474                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9475             }
9476 
9477             if (ps != null && !ps.codePath.equals(scanFile)) {
9478                 // The path has changed from what was last scanned...  check the
9479                 // version of the new path against what we have stored to determine
9480                 // what to do.
9481                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
9482                 if (pkg.mVersionCode <= ps.versionCode) {
9483                     // The system package has been updated and the code path does not match
9484                     // Ignore entry. Skip it.
9485                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
9486                             + " ignored: updated version " + ps.versionCode
9487                             + " better than this " + pkg.mVersionCode);
9488                     if (!updatedPkg.codePath.equals(scanFile)) {
9489                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
9490                                 + ps.name + " changing from " + updatedPkg.codePathString
9491                                 + " to " + scanFile);
9492                         updatedPkg.codePath = scanFile;
9493                         updatedPkg.codePathString = scanFile.toString();
9494                         updatedPkg.resourcePath = scanFile;
9495                         updatedPkg.resourcePathString = scanFile.toString();
9496                     }
9497                     updatedPkg.pkg = pkg;
9498                     updatedPkg.versionCode = pkg.mVersionCode;
9499 
9500                     // Update the disabled system child packages to point to the package too.
9501                     final int childCount = updatedPkg.childPackageNames != null
9502                             ? updatedPkg.childPackageNames.size() : 0;
9503                     for (int i = 0; i < childCount; i++) {
9504                         String childPackageName = updatedPkg.childPackageNames.get(i);
9505                         PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
9506                                 childPackageName);
9507                         if (updatedChildPkg != null) {
9508                             updatedChildPkg.pkg = pkg;
9509                             updatedChildPkg.versionCode = pkg.mVersionCode;
9510                         }
9511                     }
9512                 } else {
9513                     // The current app on the system partition is better than
9514                     // what we have updated to on the data partition; switch
9515                     // back to the system partition version.
9516                     // At this point, its safely assumed that package installation for
9517                     // apps in system partition will go through. If not there won't be a working
9518                     // version of the app
9519                     // writer
9520                     synchronized (mPackages) {
9521                         // Just remove the loaded entries from package lists.
9522                         mPackages.remove(ps.name);
9523                     }
9524 
9525                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9526                             + " reverting from " + ps.codePathString
9527                             + ": new version " + pkg.mVersionCode
9528                             + " better than installed " + ps.versionCode);
9529 
9530                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9531                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9532                     synchronized (mInstallLock) {
9533                         args.cleanUpResourcesLI();
9534                     }
9535                     synchronized (mPackages) {
9536                         mSettings.enableSystemPackageLPw(ps.name);
9537                     }
9538                     isUpdatedPkgBetter = true;
9539                 }
9540             }
9541         }
9542 
9543         String resourcePath = null;
9544         String baseResourcePath = null;
9545         if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
9546             if (ps != null && ps.resourcePathString != null) {
9547                 resourcePath = ps.resourcePathString;
9548                 baseResourcePath = ps.resourcePathString;
9549             } else {
9550                 // Should not happen at all. Just log an error.
9551                 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9552             }
9553         } else {
9554             resourcePath = pkg.codePath;
9555             baseResourcePath = pkg.baseCodePath;
9556         }
9557 
9558         // Set application objects path explicitly.
9559         pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9560         pkg.setApplicationInfoCodePath(pkg.codePath);
9561         pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9562         pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9563         pkg.setApplicationInfoResourcePath(resourcePath);
9564         pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9565         pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9566 
9567         // throw an exception if we have an update to a system application, but, it's not more
9568         // recent than the package we've already scanned
9569         if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
9570             // Set CPU Abis to application info.
9571             if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9572                 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, updatedPkg);
9573                 derivePackageAbi(pkg, scanFile, cpuAbiOverride, false, mAppLib32InstallDir);
9574             } else {
9575                 pkg.applicationInfo.primaryCpuAbi = updatedPkg.primaryCpuAbiString;
9576                 pkg.applicationInfo.secondaryCpuAbi = updatedPkg.secondaryCpuAbiString;
9577             }
9578 
9579             throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
9580                     + scanFile + " ignored: updated version " + ps.versionCode
9581                     + " better than this " + pkg.mVersionCode);
9582         }
9583 
9584         if (isUpdatedPkg) {
9585             // An updated system app will not have the PARSE_IS_SYSTEM flag set
9586             // initially
9587             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9588 
9589             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9590             // flag set initially
9591             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9592                 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9593             }
9594         }
9595 
9596         // Verify certificates against what was last scanned
9597         collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9598 
9599         /*
9600          * A new system app appeared, but we already had a non-system one of the
9601          * same name installed earlier.
9602          */
9603         boolean shouldHideSystemApp = false;
9604         if (!isUpdatedPkg && ps != null
9605                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9606             /*
9607              * Check to make sure the signatures match first. If they don't,
9608              * wipe the installed application and its data.
9609              */
9610             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9611                     != PackageManager.SIGNATURE_MATCH) {
9612                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9613                         + " signatures don't match existing userdata copy; removing");
9614                 try (PackageFreezer freezer = freezePackage(pkg.packageName,
9615                         "scanPackageInternalLI")) {
9616                     deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9617                 }
9618                 ps = null;
9619             } else {
9620                 /*
9621                  * If the newly-added system app is an older version than the
9622                  * already installed version, hide it. It will be scanned later
9623                  * and re-added like an update.
9624                  */
9625                 if (pkg.mVersionCode <= ps.versionCode) {
9626                     shouldHideSystemApp = true;
9627                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9628                             + " but new version " + pkg.mVersionCode + " better than installed "
9629                             + ps.versionCode + "; hiding system");
9630                 } else {
9631                     /*
9632                      * The newly found system app is a newer version that the
9633                      * one previously installed. Simply remove the
9634                      * already-installed application and replace it with our own
9635                      * while keeping the application data.
9636                      */
9637                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9638                             + " reverting from " + ps.codePathString + ": new version "
9639                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
9640                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9641                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9642                     synchronized (mInstallLock) {
9643                         args.cleanUpResourcesLI();
9644                     }
9645                 }
9646             }
9647         }
9648 
9649         // The apk is forward locked (not public) if its code and resources
9650         // are kept in different files. (except for app in either system or
9651         // vendor path).
9652         // TODO grab this value from PackageSettings
9653         if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9654             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9655                 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9656             }
9657         }
9658 
9659         final int userId = ((user == null) ? 0 : user.getIdentifier());
9660         if (ps != null && ps.getInstantApp(userId)) {
9661             scanFlags |= SCAN_AS_INSTANT_APP;
9662         }
9663         if (ps != null && ps.getVirtulalPreload(userId)) {
9664             scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9665         }
9666 
9667         // Note that we invoke the following method only if we are about to unpack an application
9668         PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9669                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
9670 
9671         /*
9672          * If the system app should be overridden by a previously installed
9673          * data, hide the system app now and let the /data/app scan pick it up
9674          * again.
9675          */
9676         if (shouldHideSystemApp) {
9677             synchronized (mPackages) {
9678                 mSettings.disableSystemPackageLPw(pkg.packageName, true);
9679             }
9680         }
9681 
9682         return scannedPkg;
9683     }
9684 
renameStaticSharedLibraryPackage(PackageParser.Package pkg)9685     private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9686         // Derive the new package synthetic package name
9687         pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9688                 + pkg.staticSharedLibVersion);
9689     }
9690 
fixProcessName(String defProcessName, String processName)9691     private static String fixProcessName(String defProcessName,
9692             String processName) {
9693         if (processName == null) {
9694             return defProcessName;
9695         }
9696         return processName;
9697     }
9698 
verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)9699     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9700             throws PackageManagerException {
9701         if (pkgSetting.signatures.mSignatures != null) {
9702             // Already existing package. Make sure signatures match
9703             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9704                     == PackageManager.SIGNATURE_MATCH;
9705             if (!match) {
9706                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9707                         == PackageManager.SIGNATURE_MATCH;
9708             }
9709             if (!match) {
9710                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9711                         == PackageManager.SIGNATURE_MATCH;
9712             }
9713             if (!match) {
9714                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9715                         + pkg.packageName + " signatures do not match the "
9716                         + "previously installed version; ignoring!");
9717             }
9718         }
9719 
9720         // Check for shared user signatures
9721         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9722             // Already existing package. Make sure signatures match
9723             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9724                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9725             if (!match) {
9726                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9727                         == PackageManager.SIGNATURE_MATCH;
9728             }
9729             if (!match) {
9730                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9731                         == PackageManager.SIGNATURE_MATCH;
9732             }
9733             if (!match) {
9734                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9735                         "Package " + pkg.packageName
9736                         + " has no signatures that match those in shared user "
9737                         + pkgSetting.sharedUser.name + "; ignoring!");
9738             }
9739         }
9740     }
9741 
9742     /**
9743      * Enforces that only the system UID or root's UID can call a method exposed
9744      * via Binder.
9745      *
9746      * @param message used as message if SecurityException is thrown
9747      * @throws SecurityException if the caller is not system or root
9748      */
enforceSystemOrRoot(String message)9749     private static final void enforceSystemOrRoot(String message) {
9750         final int uid = Binder.getCallingUid();
9751         if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9752             throw new SecurityException(message);
9753         }
9754     }
9755 
9756     @Override
performFstrimIfNeeded()9757     public void performFstrimIfNeeded() {
9758         enforceSystemOrRoot("Only the system can request fstrim");
9759 
9760         // Before everything else, see whether we need to fstrim.
9761         try {
9762             IStorageManager sm = PackageHelper.getStorageManager();
9763             if (sm != null) {
9764                 boolean doTrim = false;
9765                 final long interval = android.provider.Settings.Global.getLong(
9766                         mContext.getContentResolver(),
9767                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9768                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9769                 if (interval > 0) {
9770                     final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9771                     if (timeSinceLast > interval) {
9772                         doTrim = true;
9773                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9774                                 + "; running immediately");
9775                     }
9776                 }
9777                 if (doTrim) {
9778                     final boolean dexOptDialogShown;
9779                     synchronized (mPackages) {
9780                         dexOptDialogShown = mDexOptDialogShown;
9781                     }
9782                     if (!isFirstBoot() && dexOptDialogShown) {
9783                         try {
9784                             ActivityManager.getService().showBootMessage(
9785                                     mContext.getResources().getString(
9786                                             R.string.android_upgrading_fstrim), true);
9787                         } catch (RemoteException e) {
9788                         }
9789                     }
9790                     sm.runMaintenance();
9791                 }
9792             } else {
9793                 Slog.e(TAG, "storageManager service unavailable!");
9794             }
9795         } catch (RemoteException e) {
9796             // Can't happen; StorageManagerService is local
9797         }
9798     }
9799 
9800     @Override
updatePackagesIfNeeded()9801     public void updatePackagesIfNeeded() {
9802         enforceSystemOrRoot("Only the system can request package update");
9803 
9804         // We need to re-extract after an OTA.
9805         boolean causeUpgrade = isUpgrade();
9806 
9807         // First boot or factory reset.
9808         // Note: we also handle devices that are upgrading to N right now as if it is their
9809         //       first boot, as they do not have profile data.
9810         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9811 
9812         // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9813         boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9814 
9815         if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9816             return;
9817         }
9818 
9819         List<PackageParser.Package> pkgs;
9820         synchronized (mPackages) {
9821             pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9822         }
9823 
9824         final long startTime = System.nanoTime();
9825         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9826                     getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
9827                     false /* bootComplete */);
9828 
9829         final int elapsedTimeSeconds =
9830                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9831 
9832         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9833         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9834         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9835         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9836         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9837     }
9838 
9839     /*
9840      * Return the prebuilt profile path given a package base code path.
9841      */
getPrebuildProfilePath(PackageParser.Package pkg)9842     private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9843         return pkg.baseCodePath + ".prof";
9844     }
9845 
9846     /**
9847      * Performs dexopt on the set of packages in {@code packages} and returns an int array
9848      * containing statistics about the invocation. The array consists of three elements,
9849      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9850      * and {@code numberOfPackagesFailed}.
9851      */
performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, final String compilerFilter, boolean bootComplete)9852     private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9853             final String compilerFilter, boolean bootComplete) {
9854 
9855         int numberOfPackagesVisited = 0;
9856         int numberOfPackagesOptimized = 0;
9857         int numberOfPackagesSkipped = 0;
9858         int numberOfPackagesFailed = 0;
9859         final int numberOfPackagesToDexopt = pkgs.size();
9860 
9861         for (PackageParser.Package pkg : pkgs) {
9862             numberOfPackagesVisited++;
9863 
9864             boolean useProfileForDexopt = false;
9865 
9866             if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9867                 // Copy over initial preopt profiles since we won't get any JIT samples for methods
9868                 // that are already compiled.
9869                 File profileFile = new File(getPrebuildProfilePath(pkg));
9870                 // Copy profile if it exists.
9871                 if (profileFile.exists()) {
9872                     try {
9873                         // We could also do this lazily before calling dexopt in
9874                         // PackageDexOptimizer to prevent this happening on first boot. The issue
9875                         // is that we don't have a good way to say "do this only once".
9876                         if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9877                                 pkg.applicationInfo.uid, pkg.packageName)) {
9878                             Log.e(TAG, "Installer failed to copy system profile!");
9879                         } else {
9880                             // Disabled as this causes speed-profile compilation during first boot
9881                             // even if things are already compiled.
9882                             // useProfileForDexopt = true;
9883                         }
9884                     } catch (Exception e) {
9885                         Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9886                                 e);
9887                     }
9888                 } else {
9889                     PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9890                     // Handle compressed APKs in this path. Only do this for stubs with profiles to
9891                     // minimize the number off apps being speed-profile compiled during first boot.
9892                     // The other paths will not change the filter.
9893                     if (disabledPs != null && disabledPs.pkg.isStub) {
9894                         // The package is the stub one, remove the stub suffix to get the normal
9895                         // package and APK names.
9896                         String systemProfilePath =
9897                                 getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9898                         profileFile = new File(systemProfilePath);
9899                         // If we have a profile for a compressed APK, copy it to the reference
9900                         // location.
9901                         // Note that copying the profile here will cause it to override the
9902                         // reference profile every OTA even though the existing reference profile
9903                         // may have more data. We can't copy during decompression since the
9904                         // directories are not set up at that point.
9905                         if (profileFile.exists()) {
9906                             try {
9907                                 // We could also do this lazily before calling dexopt in
9908                                 // PackageDexOptimizer to prevent this happening on first boot. The
9909                                 // issue is that we don't have a good way to say "do this only
9910                                 // once".
9911                                 if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9912                                         pkg.applicationInfo.uid, pkg.packageName)) {
9913                                     Log.e(TAG, "Failed to copy system profile for stub package!");
9914                                 } else {
9915                                     useProfileForDexopt = true;
9916                                 }
9917                             } catch (Exception e) {
9918                                 Log.e(TAG, "Failed to copy profile " +
9919                                         profileFile.getAbsolutePath() + " ", e);
9920                             }
9921                         }
9922                     }
9923                 }
9924             }
9925 
9926             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9927                 if (DEBUG_DEXOPT) {
9928                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9929                 }
9930                 numberOfPackagesSkipped++;
9931                 continue;
9932             }
9933 
9934             if (DEBUG_DEXOPT) {
9935                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9936                         numberOfPackagesToDexopt + ": " + pkg.packageName);
9937             }
9938 
9939             if (showDialog) {
9940                 try {
9941                     ActivityManager.getService().showBootMessage(
9942                             mContext.getResources().getString(R.string.android_upgrading_apk,
9943                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9944                 } catch (RemoteException e) {
9945                 }
9946                 synchronized (mPackages) {
9947                     mDexOptDialogShown = true;
9948                 }
9949             }
9950 
9951             String pkgCompilerFilter = compilerFilter;
9952             if (useProfileForDexopt) {
9953                 // Use background dexopt mode to try and use the profile. Note that this does not
9954                 // guarantee usage of the profile.
9955                 pkgCompilerFilter =
9956                         PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
9957                                 PackageManagerService.REASON_BACKGROUND_DEXOPT);
9958             }
9959 
9960             // checkProfiles is false to avoid merging profiles during boot which
9961             // might interfere with background compilation (b/28612421).
9962             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9963             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9964             // trade-off worth doing to save boot time work.
9965             int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9966             int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9967                     pkg.packageName,
9968                     pkgCompilerFilter,
9969                     dexoptFlags));
9970 
9971             switch (primaryDexOptStaus) {
9972                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
9973                     numberOfPackagesOptimized++;
9974                     break;
9975                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
9976                     numberOfPackagesSkipped++;
9977                     break;
9978                 case PackageDexOptimizer.DEX_OPT_FAILED:
9979                     numberOfPackagesFailed++;
9980                     break;
9981                 default:
9982                     Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9983                     break;
9984             }
9985         }
9986 
9987         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9988                 numberOfPackagesFailed };
9989     }
9990 
9991     @Override
notifyPackageUse(String packageName, int reason)9992     public void notifyPackageUse(String packageName, int reason) {
9993         synchronized (mPackages) {
9994             final int callingUid = Binder.getCallingUid();
9995             final int callingUserId = UserHandle.getUserId(callingUid);
9996             if (getInstantAppPackageName(callingUid) != null) {
9997                 if (!isCallerSameApp(packageName, callingUid)) {
9998                     return;
9999                 }
10000             } else {
10001                 if (isInstantApp(packageName, callingUserId)) {
10002                     return;
10003                 }
10004             }
10005             notifyPackageUseLocked(packageName, reason);
10006         }
10007     }
10008 
notifyPackageUseLocked(String packageName, int reason)10009     private void notifyPackageUseLocked(String packageName, int reason) {
10010         final PackageParser.Package p = mPackages.get(packageName);
10011         if (p == null) {
10012             return;
10013         }
10014         p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
10015     }
10016 
10017     @Override
notifyDexLoad(String loadingPackageName, List<String> classLoaderNames, List<String> classPaths, String loaderIsa)10018     public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
10019             List<String> classPaths, String loaderIsa) {
10020         int userId = UserHandle.getCallingUserId();
10021         ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
10022         if (ai == null) {
10023             Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
10024                 + loadingPackageName + ", user=" + userId);
10025             return;
10026         }
10027         mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
10028     }
10029 
10030     @Override
registerDexModule(String packageName, String dexModulePath, boolean isSharedModule, IDexModuleRegisterCallback callback)10031     public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
10032             IDexModuleRegisterCallback callback) {
10033         int userId = UserHandle.getCallingUserId();
10034         ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
10035         DexManager.RegisterDexModuleResult result;
10036         if (ai == null) {
10037             Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
10038                      " calling user. package=" + packageName + ", user=" + userId);
10039             result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
10040         } else {
10041             result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
10042         }
10043 
10044         if (callback != null) {
10045             mHandler.post(() -> {
10046                 try {
10047                     callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
10048                 } catch (RemoteException e) {
10049                     Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
10050                 }
10051             });
10052         }
10053     }
10054 
10055     /**
10056      * Ask the package manager to perform a dex-opt with the given compiler filter.
10057      *
10058      * Note: exposed only for the shell command to allow moving packages explicitly to a
10059      *       definite state.
10060      */
10061     @Override
performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force, boolean bootComplete, String splitName)10062     public boolean performDexOptMode(String packageName,
10063             boolean checkProfiles, String targetCompilerFilter, boolean force,
10064             boolean bootComplete, String splitName) {
10065         int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
10066                 (force ? DexoptOptions.DEXOPT_FORCE : 0) |
10067                 (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
10068         return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
10069                 splitName, flags));
10070     }
10071 
10072     /**
10073      * Ask the package manager to perform a dex-opt with the given compiler filter on the
10074      * secondary dex files belonging to the given package.
10075      *
10076      * Note: exposed only for the shell command to allow moving packages explicitly to a
10077      *       definite state.
10078      */
10079     @Override
performDexOptSecondary(String packageName, String compilerFilter, boolean force)10080     public boolean performDexOptSecondary(String packageName, String compilerFilter,
10081             boolean force) {
10082         int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
10083                 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
10084                 DexoptOptions.DEXOPT_BOOT_COMPLETE |
10085                 (force ? DexoptOptions.DEXOPT_FORCE : 0);
10086         return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
10087     }
10088 
performDexOpt(DexoptOptions options)10089     /*package*/ boolean performDexOpt(DexoptOptions options) {
10090         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10091             return false;
10092         } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
10093             return false;
10094         }
10095 
10096         if (options.isDexoptOnlySecondaryDex()) {
10097             return mDexManager.dexoptSecondaryDex(options);
10098         } else {
10099             int dexoptStatus = performDexOptWithStatus(options);
10100             return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
10101         }
10102     }
10103 
10104     /**
10105      * Perform dexopt on the given package and return one of following result:
10106      *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
10107      *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
10108      *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
10109      */
performDexOptWithStatus(DexoptOptions options)10110     /* package */ int performDexOptWithStatus(DexoptOptions options) {
10111         return performDexOptTraced(options);
10112     }
10113 
performDexOptTraced(DexoptOptions options)10114     private int performDexOptTraced(DexoptOptions options) {
10115         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10116         try {
10117             return performDexOptInternal(options);
10118         } finally {
10119             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10120         }
10121     }
10122 
10123     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
10124     // if the package can now be considered up to date for the given filter.
performDexOptInternal(DexoptOptions options)10125     private int performDexOptInternal(DexoptOptions options) {
10126         PackageParser.Package p;
10127         synchronized (mPackages) {
10128             p = mPackages.get(options.getPackageName());
10129             if (p == null) {
10130                 // Package could not be found. Report failure.
10131                 return PackageDexOptimizer.DEX_OPT_FAILED;
10132             }
10133             mPackageUsage.maybeWriteAsync(mPackages);
10134             mCompilerStats.maybeWriteAsync();
10135         }
10136         long callingId = Binder.clearCallingIdentity();
10137         try {
10138             synchronized (mInstallLock) {
10139                 return performDexOptInternalWithDependenciesLI(p, options);
10140             }
10141         } finally {
10142             Binder.restoreCallingIdentity(callingId);
10143         }
10144     }
10145 
getOptimizablePackages()10146     public ArraySet<String> getOptimizablePackages() {
10147         ArraySet<String> pkgs = new ArraySet<String>();
10148         synchronized (mPackages) {
10149             for (PackageParser.Package p : mPackages.values()) {
10150                 if (PackageDexOptimizer.canOptimizePackage(p)) {
10151                     pkgs.add(p.packageName);
10152                 }
10153             }
10154         }
10155         return pkgs;
10156     }
10157 
performDexOptInternalWithDependenciesLI(PackageParser.Package p, DexoptOptions options)10158     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
10159             DexoptOptions options) {
10160         // Select the dex optimizer based on the force parameter.
10161         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
10162         //       allocate an object here.
10163         PackageDexOptimizer pdo = options.isForce()
10164                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
10165                 : mPackageDexOptimizer;
10166 
10167         // Dexopt all dependencies first. Note: we ignore the return value and march on
10168         // on errors.
10169         // Note that we are going to call performDexOpt on those libraries as many times as
10170         // they are referenced in packages. When we do a batch of performDexOpt (for example
10171         // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
10172         // and the first package that uses the library will dexopt it. The
10173         // others will see that the compiled code for the library is up to date.
10174         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
10175         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
10176         if (!deps.isEmpty()) {
10177             DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
10178                     options.getCompilerFilter(), options.getSplitName(),
10179                     options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
10180             for (PackageParser.Package depPackage : deps) {
10181                 // TODO: Analyze and investigate if we (should) profile libraries.
10182                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
10183                         getOrCreateCompilerPackageStats(depPackage),
10184                     mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
10185             }
10186         }
10187         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
10188                 getOrCreateCompilerPackageStats(p),
10189                 mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
10190     }
10191 
10192     /**
10193      * Reconcile the information we have about the secondary dex files belonging to
10194      * {@code packagName} and the actual dex files. For all dex files that were
10195      * deleted, update the internal records and delete the generated oat files.
10196      */
10197     @Override
reconcileSecondaryDexFiles(String packageName)10198     public void reconcileSecondaryDexFiles(String packageName) {
10199         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10200             return;
10201         } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
10202             return;
10203         }
10204         mDexManager.reconcileSecondaryDexFiles(packageName);
10205     }
10206 
10207     // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
10208     // a reference there.
getDexManager()10209     /*package*/ DexManager getDexManager() {
10210         return mDexManager;
10211     }
10212 
10213     /**
10214      * Execute the background dexopt job immediately.
10215      */
10216     @Override
runBackgroundDexoptJob()10217     public boolean runBackgroundDexoptJob() {
10218         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10219             return false;
10220         }
10221         return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
10222     }
10223 
findSharedNonSystemLibraries(PackageParser.Package p)10224     List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
10225         if (p.usesLibraries != null || p.usesOptionalLibraries != null
10226                 || p.usesStaticLibraries != null) {
10227             ArrayList<PackageParser.Package> retValue = new ArrayList<>();
10228             Set<String> collectedNames = new HashSet<>();
10229             findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
10230 
10231             retValue.remove(p);
10232 
10233             return retValue;
10234         } else {
10235             return Collections.emptyList();
10236         }
10237     }
10238 
findSharedNonSystemLibrariesRecursive(PackageParser.Package p, ArrayList<PackageParser.Package> collected, Set<String> collectedNames)10239     private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
10240             ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10241         if (!collectedNames.contains(p.packageName)) {
10242             collectedNames.add(p.packageName);
10243             collected.add(p);
10244 
10245             if (p.usesLibraries != null) {
10246                 findSharedNonSystemLibrariesRecursive(p.usesLibraries,
10247                         null, collected, collectedNames);
10248             }
10249             if (p.usesOptionalLibraries != null) {
10250                 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
10251                         null, collected, collectedNames);
10252             }
10253             if (p.usesStaticLibraries != null) {
10254                 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
10255                         p.usesStaticLibrariesVersions, collected, collectedNames);
10256             }
10257         }
10258     }
10259 
findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions, ArrayList<PackageParser.Package> collected, Set<String> collectedNames)10260     private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
10261             ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10262         final int libNameCount = libs.size();
10263         for (int i = 0; i < libNameCount; i++) {
10264             String libName = libs.get(i);
10265             int version = (versions != null && versions.length == libNameCount)
10266                     ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
10267             PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
10268             if (libPkg != null) {
10269                 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
10270             }
10271         }
10272     }
10273 
findSharedNonSystemLibrary(String name, int version)10274     private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
10275         synchronized (mPackages) {
10276             SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
10277             if (libEntry != null) {
10278                 return mPackages.get(libEntry.apk);
10279             }
10280             return null;
10281         }
10282     }
10283 
getSharedLibraryEntryLPr(String name, int version)10284     private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
10285         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10286         if (versionedLib == null) {
10287             return null;
10288         }
10289         return versionedLib.get(version);
10290     }
10291 
getLatestSharedLibraVersionLPr(PackageParser.Package pkg)10292     private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
10293         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10294                 pkg.staticSharedLibName);
10295         if (versionedLib == null) {
10296             return null;
10297         }
10298         int previousLibVersion = -1;
10299         final int versionCount = versionedLib.size();
10300         for (int i = 0; i < versionCount; i++) {
10301             final int libVersion = versionedLib.keyAt(i);
10302             if (libVersion < pkg.staticSharedLibVersion) {
10303                 previousLibVersion = Math.max(previousLibVersion, libVersion);
10304             }
10305         }
10306         if (previousLibVersion >= 0) {
10307             return versionedLib.get(previousLibVersion);
10308         }
10309         return null;
10310     }
10311 
shutdown()10312     public void shutdown() {
10313         mPackageUsage.writeNow(mPackages);
10314         mCompilerStats.writeNow();
10315         mDexManager.writePackageDexUsageNow();
10316     }
10317 
10318     @Override
dumpProfiles(String packageName)10319     public void dumpProfiles(String packageName) {
10320         PackageParser.Package pkg;
10321         synchronized (mPackages) {
10322             pkg = mPackages.get(packageName);
10323             if (pkg == null) {
10324                 throw new IllegalArgumentException("Unknown package: " + packageName);
10325             }
10326         }
10327         /* Only the shell, root, or the app user should be able to dump profiles. */
10328         int callingUid = Binder.getCallingUid();
10329         if (callingUid != Process.SHELL_UID &&
10330             callingUid != Process.ROOT_UID &&
10331             callingUid != pkg.applicationInfo.uid) {
10332             throw new SecurityException("dumpProfiles");
10333         }
10334 
10335         synchronized (mInstallLock) {
10336             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10337             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
10338             try {
10339                 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
10340                 String codePaths = TextUtils.join(";", allCodePaths);
10341                 mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
10342             } catch (InstallerException e) {
10343                 Slog.w(TAG, "Failed to dump profiles", e);
10344             }
10345             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10346         }
10347     }
10348 
10349     @Override
forceDexOpt(String packageName)10350     public void forceDexOpt(String packageName) {
10351         enforceSystemOrRoot("forceDexOpt");
10352 
10353         PackageParser.Package pkg;
10354         synchronized (mPackages) {
10355             pkg = mPackages.get(packageName);
10356             if (pkg == null) {
10357                 throw new IllegalArgumentException("Unknown package: " + packageName);
10358             }
10359         }
10360 
10361         synchronized (mInstallLock) {
10362             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10363 
10364             // Whoever is calling forceDexOpt wants a compiled package.
10365             // Don't use profiles since that may cause compilation to be skipped.
10366             final int res = performDexOptInternalWithDependenciesLI(
10367                     pkg,
10368                     new DexoptOptions(packageName,
10369                             getDefaultCompilerFilter(),
10370                             DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10371 
10372             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10373             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10374                 throw new IllegalStateException("Failed to dexopt: " + res);
10375             }
10376         }
10377     }
10378 
verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)10379     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10380         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10381             Slog.w(TAG, "Unable to update from " + oldPkg.name
10382                     + " to " + newPkg.packageName
10383                     + ": old package not in system partition");
10384             return false;
10385         } else if (mPackages.get(oldPkg.name) != null) {
10386             Slog.w(TAG, "Unable to update from " + oldPkg.name
10387                     + " to " + newPkg.packageName
10388                     + ": old package still exists");
10389             return false;
10390         }
10391         return true;
10392     }
10393 
removeCodePathLI(File codePath)10394     void removeCodePathLI(File codePath) {
10395         if (codePath.isDirectory()) {
10396             try {
10397                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
10398             } catch (InstallerException e) {
10399                 Slog.w(TAG, "Failed to remove code path", e);
10400             }
10401         } else {
10402             codePath.delete();
10403         }
10404     }
10405 
resolveUserIds(int userId)10406     private int[] resolveUserIds(int userId) {
10407         return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10408     }
10409 
clearAppDataLIF(PackageParser.Package pkg, int userId, int flags)10410     private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10411         if (pkg == null) {
10412             Slog.wtf(TAG, "Package was null!", new Throwable());
10413             return;
10414         }
10415         clearAppDataLeafLIF(pkg, userId, flags);
10416         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10417         for (int i = 0; i < childCount; i++) {
10418             clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10419         }
10420     }
10421 
clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags)10422     private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10423         final PackageSetting ps;
10424         synchronized (mPackages) {
10425             ps = mSettings.mPackages.get(pkg.packageName);
10426         }
10427         for (int realUserId : resolveUserIds(userId)) {
10428             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10429             try {
10430                 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10431                         ceDataInode);
10432             } catch (InstallerException e) {
10433                 Slog.w(TAG, String.valueOf(e));
10434             }
10435         }
10436     }
10437 
destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags)10438     private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10439         if (pkg == null) {
10440             Slog.wtf(TAG, "Package was null!", new Throwable());
10441             return;
10442         }
10443         destroyAppDataLeafLIF(pkg, userId, flags);
10444         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10445         for (int i = 0; i < childCount; i++) {
10446             destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10447         }
10448     }
10449 
destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags)10450     private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10451         final PackageSetting ps;
10452         synchronized (mPackages) {
10453             ps = mSettings.mPackages.get(pkg.packageName);
10454         }
10455         for (int realUserId : resolveUserIds(userId)) {
10456             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10457             try {
10458                 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10459                         ceDataInode);
10460             } catch (InstallerException e) {
10461                 Slog.w(TAG, String.valueOf(e));
10462             }
10463             mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10464         }
10465     }
10466 
destroyAppProfilesLIF(PackageParser.Package pkg, int userId)10467     private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
10468         if (pkg == null) {
10469             Slog.wtf(TAG, "Package was null!", new Throwable());
10470             return;
10471         }
10472         destroyAppProfilesLeafLIF(pkg);
10473         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10474         for (int i = 0; i < childCount; i++) {
10475             destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10476         }
10477     }
10478 
destroyAppProfilesLeafLIF(PackageParser.Package pkg)10479     private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10480         try {
10481             mInstaller.destroyAppProfiles(pkg.packageName);
10482         } catch (InstallerException e) {
10483             Slog.w(TAG, String.valueOf(e));
10484         }
10485     }
10486 
clearAppProfilesLIF(PackageParser.Package pkg, int userId)10487     private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10488         if (pkg == null) {
10489             Slog.wtf(TAG, "Package was null!", new Throwable());
10490             return;
10491         }
10492         clearAppProfilesLeafLIF(pkg);
10493         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10494         for (int i = 0; i < childCount; i++) {
10495             clearAppProfilesLeafLIF(pkg.childPackages.get(i));
10496         }
10497     }
10498 
clearAppProfilesLeafLIF(PackageParser.Package pkg)10499     private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
10500         try {
10501             mInstaller.clearAppProfiles(pkg.packageName);
10502         } catch (InstallerException e) {
10503             Slog.w(TAG, String.valueOf(e));
10504         }
10505     }
10506 
setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, long lastUpdateTime)10507     private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10508             long lastUpdateTime) {
10509         // Set parent install/update time
10510         PackageSetting ps = (PackageSetting) pkg.mExtras;
10511         if (ps != null) {
10512             ps.firstInstallTime = firstInstallTime;
10513             ps.lastUpdateTime = lastUpdateTime;
10514         }
10515         // Set children install/update time
10516         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10517         for (int i = 0; i < childCount; i++) {
10518             PackageParser.Package childPkg = pkg.childPackages.get(i);
10519             ps = (PackageSetting) childPkg.mExtras;
10520             if (ps != null) {
10521                 ps.firstInstallTime = firstInstallTime;
10522                 ps.lastUpdateTime = lastUpdateTime;
10523             }
10524         }
10525     }
10526 
addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, PackageParser.Package changingLib)10527     private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
10528             PackageParser.Package changingLib) {
10529         if (file.path != null) {
10530             usesLibraryFiles.add(file.path);
10531             return;
10532         }
10533         PackageParser.Package p = mPackages.get(file.apk);
10534         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
10535             // If we are doing this while in the middle of updating a library apk,
10536             // then we need to make sure to use that new apk for determining the
10537             // dependencies here.  (We haven't yet finished committing the new apk
10538             // to the package manager state.)
10539             if (p == null || p.packageName.equals(changingLib.packageName)) {
10540                 p = changingLib;
10541             }
10542         }
10543         if (p != null) {
10544             usesLibraryFiles.addAll(p.getAllCodePaths());
10545             if (p.usesLibraryFiles != null) {
10546                 Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10547             }
10548         }
10549     }
10550 
updateSharedLibrariesLPr(PackageParser.Package pkg, PackageParser.Package changingLib)10551     private void updateSharedLibrariesLPr(PackageParser.Package pkg,
10552             PackageParser.Package changingLib) throws PackageManagerException {
10553         if (pkg == null) {
10554             return;
10555         }
10556         ArraySet<String> usesLibraryFiles = null;
10557         if (pkg.usesLibraries != null) {
10558             usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
10559                     null, null, pkg.packageName, changingLib, true,
10560                     pkg.applicationInfo.targetSdkVersion, null);
10561         }
10562         if (pkg.usesStaticLibraries != null) {
10563             usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
10564                     pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10565                     pkg.packageName, changingLib, true,
10566                     pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10567         }
10568         if (pkg.usesOptionalLibraries != null) {
10569             usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
10570                     null, null, pkg.packageName, changingLib, false,
10571                     pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10572         }
10573         if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
10574             pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10575         } else {
10576             pkg.usesLibraryFiles = null;
10577         }
10578     }
10579 
addSharedLibrariesLPw(@onNull List<String> requestedLibraries, @Nullable int[] requiredVersions, @Nullable String[][] requiredCertDigests, @NonNull String packageName, @Nullable PackageParser.Package changingLib, boolean required, int targetSdk, @Nullable ArraySet<String> outUsedLibraries)10580     private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
10581             @Nullable int[] requiredVersions, @Nullable String[][] requiredCertDigests,
10582             @NonNull String packageName, @Nullable PackageParser.Package changingLib,
10583             boolean required, int targetSdk, @Nullable ArraySet<String> outUsedLibraries)
10584             throws PackageManagerException {
10585         final int libCount = requestedLibraries.size();
10586         for (int i = 0; i < libCount; i++) {
10587             final String libName = requestedLibraries.get(i);
10588             final int libVersion = requiredVersions != null ? requiredVersions[i]
10589                     : SharedLibraryInfo.VERSION_UNDEFINED;
10590             final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
10591             if (libEntry == null) {
10592                 if (required) {
10593                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10594                             "Package " + packageName + " requires unavailable shared library "
10595                                     + libName + "; failing!");
10596                 } else if (DEBUG_SHARED_LIBRARIES) {
10597                     Slog.i(TAG, "Package " + packageName
10598                             + " desires unavailable shared library "
10599                             + libName + "; ignoring!");
10600                 }
10601             } else {
10602                 if (requiredVersions != null && requiredCertDigests != null) {
10603                     if (libEntry.info.getVersion() != requiredVersions[i]) {
10604                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10605                             "Package " + packageName + " requires unavailable static shared"
10606                                     + " library " + libName + " version "
10607                                     + libEntry.info.getVersion() + "; failing!");
10608                     }
10609 
10610                     PackageParser.Package libPkg = mPackages.get(libEntry.apk);
10611                     if (libPkg == null) {
10612                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10613                                 "Package " + packageName + " requires unavailable static shared"
10614                                         + " library; failing!");
10615                     }
10616 
10617                     final String[] expectedCertDigests = requiredCertDigests[i];
10618                     // For apps targeting O MR1 we require explicit enumeration of all certs.
10619                     final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
10620                             ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
10621                             : PackageUtils.computeSignaturesSha256Digests(
10622                                     new Signature[]{libPkg.mSignatures[0]});
10623 
10624                     // Take a shortcut if sizes don't match. Note that if an app doesn't
10625                     // target O we don't parse the "additional-certificate" tags similarly
10626                     // how we only consider all certs only for apps targeting O (see above).
10627                     // Therefore, the size check is safe to make.
10628                     if (expectedCertDigests.length != libCertDigests.length) {
10629                         throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10630                                 "Package " + packageName + " requires differently signed" +
10631                                         " static sDexLoadReporter.java:45.19hared library; failing!");
10632                     }
10633 
10634                     // Use a predictable order as signature order may vary
10635                     Arrays.sort(libCertDigests);
10636                     Arrays.sort(expectedCertDigests);
10637 
10638                     final int certCount = libCertDigests.length;
10639                     for (int j = 0; j < certCount; j++) {
10640                         if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10641                             throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10642                                     "Package " + packageName + " requires differently signed" +
10643                                             " static shared library; failing!");
10644                         }
10645                     }
10646                 }
10647 
10648                 if (outUsedLibraries == null) {
10649                     outUsedLibraries = new ArraySet<>();
10650                 }
10651                 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
10652             }
10653         }
10654         return outUsedLibraries;
10655     }
10656 
hasString(List<String> list, List<String> which)10657     private static boolean hasString(List<String> list, List<String> which) {
10658         if (list == null) {
10659             return false;
10660         }
10661         for (int i=list.size()-1; i>=0; i--) {
10662             for (int j=which.size()-1; j>=0; j--) {
10663                 if (which.get(j).equals(list.get(i))) {
10664                     return true;
10665                 }
10666             }
10667         }
10668         return false;
10669     }
10670 
updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)10671     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10672             PackageParser.Package changingPkg) {
10673         ArrayList<PackageParser.Package> res = null;
10674         for (PackageParser.Package pkg : mPackages.values()) {
10675             if (changingPkg != null
10676                     && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10677                     && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10678                     && !ArrayUtils.contains(pkg.usesStaticLibraries,
10679                             changingPkg.staticSharedLibName)) {
10680                 return null;
10681             }
10682             if (res == null) {
10683                 res = new ArrayList<>();
10684             }
10685             res.add(pkg);
10686             try {
10687                 updateSharedLibrariesLPr(pkg, changingPkg);
10688             } catch (PackageManagerException e) {
10689                 // If a system app update or an app and a required lib missing we
10690                 // delete the package and for updated system apps keep the data as
10691                 // it is better for the user to reinstall than to be in an limbo
10692                 // state. Also libs disappearing under an app should never happen
10693                 // - just in case.
10694                 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10695                     final int flags = pkg.isUpdatedSystemApp()
10696                             ? PackageManager.DELETE_KEEP_DATA : 0;
10697                     deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10698                             flags , null, true, null);
10699                 }
10700                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10701             }
10702         }
10703         return res;
10704     }
10705 
10706     /**
10707      * Derive the value of the {@code cpuAbiOverride} based on the provided
10708      * value and an optional stored value from the package settings.
10709      */
deriveAbiOverride(String abiOverride, PackageSetting settings)10710     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10711         String cpuAbiOverride = null;
10712 
10713         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10714             cpuAbiOverride = null;
10715         } else if (abiOverride != null) {
10716             cpuAbiOverride = abiOverride;
10717         } else if (settings != null) {
10718             cpuAbiOverride = settings.cpuAbiOverrideString;
10719         }
10720 
10721         return cpuAbiOverride;
10722     }
10723 
scanPackageTracedLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)10724     private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10725             final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10726                     throws PackageManagerException {
10727         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10728         // If the package has children and this is the first dive in the function
10729         // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10730         // whether all packages (parent and children) would be successfully scanned
10731         // before the actual scan since scanning mutates internal state and we want
10732         // to atomically install the package and its children.
10733         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10734             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10735                 scanFlags |= SCAN_CHECK_ONLY;
10736             }
10737         } else {
10738             scanFlags &= ~SCAN_CHECK_ONLY;
10739         }
10740 
10741         final PackageParser.Package scannedPkg;
10742         try {
10743             // Scan the parent
10744             scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10745             // Scan the children
10746             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10747             for (int i = 0; i < childCount; i++) {
10748                 PackageParser.Package childPkg = pkg.childPackages.get(i);
10749                 scanPackageLI(childPkg, policyFlags,
10750                         scanFlags, currentTime, user);
10751             }
10752         } finally {
10753             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10754         }
10755 
10756         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10757             return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10758         }
10759 
10760         return scannedPkg;
10761     }
10762 
scanPackageLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)10763     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10764             int scanFlags, long currentTime, @Nullable UserHandle user)
10765                     throws PackageManagerException {
10766         boolean success = false;
10767         try {
10768             final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10769                     currentTime, user);
10770             success = true;
10771             return res;
10772         } finally {
10773             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10774                 // DELETE_DATA_ON_FAILURES is only used by frozen paths
10775                 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10776                         StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10777                 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10778             }
10779         }
10780     }
10781 
10782     /**
10783      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10784      */
apkHasCode(String fileName)10785     private static boolean apkHasCode(String fileName) {
10786         StrictJarFile jarFile = null;
10787         try {
10788             jarFile = new StrictJarFile(fileName,
10789                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10790             return jarFile.findEntry("classes.dex") != null;
10791         } catch (IOException ignore) {
10792         } finally {
10793             try {
10794                 if (jarFile != null) {
10795                     jarFile.close();
10796                 }
10797             } catch (IOException ignore) {}
10798         }
10799         return false;
10800     }
10801 
10802     /**
10803      * Enforces code policy for the package. This ensures that if an APK has
10804      * declared hasCode="true" in its manifest that the APK actually contains
10805      * code.
10806      *
10807      * @throws PackageManagerException If bytecode could not be found when it should exist
10808      */
assertCodePolicy(PackageParser.Package pkg)10809     private static void assertCodePolicy(PackageParser.Package pkg)
10810             throws PackageManagerException {
10811         final boolean shouldHaveCode =
10812                 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10813         if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10814             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10815                     "Package " + pkg.baseCodePath + " code is missing");
10816         }
10817 
10818         if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10819             for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10820                 final boolean splitShouldHaveCode =
10821                         (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10822                 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10823                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10824                             "Package " + pkg.splitCodePaths[i] + " code is missing");
10825                 }
10826             }
10827         }
10828     }
10829 
scanPackageDirtyLI(PackageParser.Package pkg, final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)10830     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10831             final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10832                     throws PackageManagerException {
10833         if (DEBUG_PACKAGE_SCANNING) {
10834             if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10835                 Log.d(TAG, "Scanning package " + pkg.packageName);
10836         }
10837 
10838         applyPolicy(pkg, policyFlags);
10839 
10840         assertPackageIsValid(pkg, policyFlags, scanFlags);
10841 
10842         // Initialize package source and resource directories
10843         final File scanFile = new File(pkg.codePath);
10844         final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10845         final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10846 
10847         SharedUserSetting suid = null;
10848         PackageSetting pkgSetting = null;
10849 
10850         // Getting the package setting may have a side-effect, so if we
10851         // are only checking if scan would succeed, stash a copy of the
10852         // old setting to restore at the end.
10853         PackageSetting nonMutatedPs = null;
10854 
10855         // We keep references to the derived CPU Abis from settings in oder to reuse
10856         // them in the case where we're not upgrading or booting for the first time.
10857         String primaryCpuAbiFromSettings = null;
10858         String secondaryCpuAbiFromSettings = null;
10859 
10860         final PackageParser.Package oldPkg;
10861 
10862         // writer
10863         synchronized (mPackages) {
10864             if (pkg.mSharedUserId != null) {
10865                 // SIDE EFFECTS; may potentially allocate a new shared user
10866                 suid = mSettings.getSharedUserLPw(
10867                         pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10868                 if (DEBUG_PACKAGE_SCANNING) {
10869                     if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10870                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10871                                 + "): packages=" + suid.packages);
10872                 }
10873             }
10874 
10875             // Check if we are renaming from an original package name.
10876             PackageSetting origPackage = null;
10877             String realName = null;
10878             if (pkg.mOriginalPackages != null) {
10879                 // This package may need to be renamed to a previously
10880                 // installed name.  Let's check on that...
10881                 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10882                 if (pkg.mOriginalPackages.contains(renamed)) {
10883                     // This package had originally been installed as the
10884                     // original name, and we have already taken care of
10885                     // transitioning to the new one.  Just update the new
10886                     // one to continue using the old name.
10887                     realName = pkg.mRealPackage;
10888                     if (!pkg.packageName.equals(renamed)) {
10889                         // Callers into this function may have already taken
10890                         // care of renaming the package; only do it here if
10891                         // it is not already done.
10892                         pkg.setPackageName(renamed);
10893                     }
10894                 } else {
10895                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10896                         if ((origPackage = mSettings.getPackageLPr(
10897                                 pkg.mOriginalPackages.get(i))) != null) {
10898                             // We do have the package already installed under its
10899                             // original name...  should we use it?
10900                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10901                                 // New package is not compatible with original.
10902                                 origPackage = null;
10903                                 continue;
10904                             } else if (origPackage.sharedUser != null) {
10905                                 // Make sure uid is compatible between packages.
10906                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10907                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10908                                             + " to " + pkg.packageName + ": old uid "
10909                                             + origPackage.sharedUser.name
10910                                             + " differs from " + pkg.mSharedUserId);
10911                                     origPackage = null;
10912                                     continue;
10913                                 }
10914                                 // TODO: Add case when shared user id is added [b/28144775]
10915                             } else {
10916                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10917                                         + pkg.packageName + " to old name " + origPackage.name);
10918                             }
10919                             break;
10920                         }
10921                     }
10922                 }
10923             }
10924 
10925             if (mTransferedPackages.contains(pkg.packageName)) {
10926                 Slog.w(TAG, "Package " + pkg.packageName
10927                         + " was transferred to another, but its .apk remains");
10928             }
10929 
10930             // See comments in nonMutatedPs declaration
10931             if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10932                 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10933                 if (foundPs != null) {
10934                     nonMutatedPs = new PackageSetting(foundPs);
10935                 }
10936             }
10937 
10938             if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10939                 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10940                 if (foundPs != null) {
10941                     primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10942                     secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10943                 }
10944             }
10945 
10946             pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10947             if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10948                 PackageManagerService.reportSettingsProblem(Log.WARN,
10949                         "Package " + pkg.packageName + " shared user changed from "
10950                                 + (pkgSetting.sharedUser != null
10951                                         ? pkgSetting.sharedUser.name : "<nothing>")
10952                                 + " to "
10953                                 + (suid != null ? suid.name : "<nothing>")
10954                                 + "; replacing with new");
10955                 pkgSetting = null;
10956             }
10957             final PackageSetting oldPkgSetting =
10958                     pkgSetting == null ? null : new PackageSetting(pkgSetting);
10959             final PackageSetting disabledPkgSetting =
10960                     mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10961 
10962             if (oldPkgSetting == null) {
10963                 oldPkg = null;
10964             } else {
10965                 oldPkg = oldPkgSetting.pkg;
10966             }
10967 
10968             String[] usesStaticLibraries = null;
10969             if (pkg.usesStaticLibraries != null) {
10970                 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10971                 pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10972             }
10973 
10974             if (pkgSetting == null) {
10975                 final String parentPackageName = (pkg.parentPackage != null)
10976                         ? pkg.parentPackage.packageName : null;
10977                 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10978                 final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10979                 // REMOVE SharedUserSetting from method; update in a separate call
10980                 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10981                         disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10982                         pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10983                         pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10984                         pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10985                         true /*allowInstall*/, instantApp, virtualPreload,
10986                         parentPackageName, pkg.getChildPackageNames(),
10987                         UserManagerService.getInstance(), usesStaticLibraries,
10988                         pkg.usesStaticLibrariesVersions);
10989                 // SIDE EFFECTS; updates system state; move elsewhere
10990                 if (origPackage != null) {
10991                     mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10992                 }
10993                 mSettings.addUserToSettingLPw(pkgSetting);
10994             } else {
10995                 // REMOVE SharedUserSetting from method; update in a separate call.
10996                 //
10997                 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10998                 // secondaryCpuAbi are not known at this point so we always update them
10999                 // to null here, only to reset them at a later point.
11000                 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
11001                         pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
11002                         pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
11003                         pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
11004                         UserManagerService.getInstance(), usesStaticLibraries,
11005                         pkg.usesStaticLibrariesVersions);
11006             }
11007             // SIDE EFFECTS; persists system state to files on disk; move elsewhere
11008             mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
11009 
11010             // SIDE EFFECTS; modifies system state; move elsewhere
11011             if (pkgSetting.origPackage != null) {
11012                 // If we are first transitioning from an original package,
11013                 // fix up the new package's name now.  We need to do this after
11014                 // looking up the package under its new name, so getPackageLP
11015                 // can take care of fiddling things correctly.
11016                 pkg.setPackageName(origPackage.name);
11017 
11018                 // File a report about this.
11019                 String msg = "New package " + pkgSetting.realName
11020                         + " renamed to replace old package " + pkgSetting.name;
11021                 reportSettingsProblem(Log.WARN, msg);
11022 
11023                 // Make a note of it.
11024                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11025                     mTransferedPackages.add(origPackage.name);
11026                 }
11027 
11028                 // No longer need to retain this.
11029                 pkgSetting.origPackage = null;
11030             }
11031 
11032             // SIDE EFFECTS; modifies system state; move elsewhere
11033             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
11034                 // Make a note of it.
11035                 mTransferedPackages.add(pkg.packageName);
11036             }
11037 
11038             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
11039                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
11040             }
11041 
11042             if ((scanFlags & SCAN_BOOTING) == 0
11043                     && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11044                 // Check all shared libraries and map to their actual file path.
11045                 // We only do this here for apps not on a system dir, because those
11046                 // are the only ones that can fail an install due to this.  We
11047                 // will take care of the system apps by updating all of their
11048                 // library paths after the scan is done. Also during the initial
11049                 // scan don't update any libs as we do this wholesale after all
11050                 // apps are scanned to avoid dependency based scanning.
11051                 updateSharedLibrariesLPr(pkg, null);
11052             }
11053 
11054             if (mFoundPolicyFile) {
11055                 SELinuxMMAC.assignSeInfoValue(pkg);
11056             }
11057             pkg.applicationInfo.uid = pkgSetting.appId;
11058             pkg.mExtras = pkgSetting;
11059 
11060 
11061             // Static shared libs have same package with different versions where
11062             // we internally use a synthetic package name to allow multiple versions
11063             // of the same package, therefore we need to compare signatures against
11064             // the package setting for the latest library version.
11065             PackageSetting signatureCheckPs = pkgSetting;
11066             if (pkg.applicationInfo.isStaticSharedLibrary()) {
11067                 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
11068                 if (libraryEntry != null) {
11069                     signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
11070                 }
11071             }
11072 
11073             if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
11074                 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
11075                     // We just determined the app is signed correctly, so bring
11076                     // over the latest parsed certs.
11077                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
11078                 } else {
11079                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11080                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
11081                                 "Package " + pkg.packageName + " upgrade keys do not match the "
11082                                 + "previously installed version");
11083                     } else {
11084                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
11085                         String msg = "System package " + pkg.packageName
11086                                 + " signature changed; retaining data.";
11087                         reportSettingsProblem(Log.WARN, msg);
11088                     }
11089                 }
11090             } else {
11091                 try {
11092                     // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
11093                     verifySignaturesLP(signatureCheckPs, pkg);
11094                     // We just determined the app is signed correctly, so bring
11095                     // over the latest parsed certs.
11096                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
11097                 } catch (PackageManagerException e) {
11098                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11099                         throw e;
11100                     }
11101                     // The signature has changed, but this package is in the system
11102                     // image...  let's recover!
11103                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
11104                     // However...  if this package is part of a shared user, but it
11105                     // doesn't match the signature of the shared user, let's fail.
11106                     // What this means is that you can't change the signatures
11107                     // associated with an overall shared user, which doesn't seem all
11108                     // that unreasonable.
11109                     if (signatureCheckPs.sharedUser != null) {
11110                         if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
11111                                 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
11112                             throw new PackageManagerException(
11113                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
11114                                     "Signature mismatch for shared user: "
11115                                             + pkgSetting.sharedUser);
11116                         }
11117                     }
11118                     // File a report about this.
11119                     String msg = "System package " + pkg.packageName
11120                             + " signature changed; retaining data.";
11121                     reportSettingsProblem(Log.WARN, msg);
11122                 }
11123             }
11124 
11125             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
11126                 // This package wants to adopt ownership of permissions from
11127                 // another package.
11128                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
11129                     final String origName = pkg.mAdoptPermissions.get(i);
11130                     final PackageSetting orig = mSettings.getPackageLPr(origName);
11131                     if (orig != null) {
11132                         if (verifyPackageUpdateLPr(orig, pkg)) {
11133                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
11134                                     + pkg.packageName);
11135                             // SIDE EFFECTS; updates permissions system state; move elsewhere
11136                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
11137                         }
11138                     }
11139                 }
11140             }
11141         }
11142 
11143         pkg.applicationInfo.processName = fixProcessName(
11144                 pkg.applicationInfo.packageName,
11145                 pkg.applicationInfo.processName);
11146 
11147         if (pkg != mPlatformPackage) {
11148             // Get all of our default paths setup
11149             pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
11150         }
11151 
11152         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
11153 
11154         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
11155             if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
11156                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
11157                 final boolean extractNativeLibs = !pkg.isLibrary();
11158                 derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
11159                         mAppLib32InstallDir);
11160                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11161 
11162                 // Some system apps still use directory structure for native libraries
11163                 // in which case we might end up not detecting abi solely based on apk
11164                 // structure. Try to detect abi based on directory structure.
11165                 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
11166                         pkg.applicationInfo.primaryCpuAbi == null) {
11167                     setBundledAppAbisAndRoots(pkg, pkgSetting);
11168                     setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11169                 }
11170             } else {
11171                 // This is not a first boot or an upgrade, don't bother deriving the
11172                 // ABI during the scan. Instead, trust the value that was stored in the
11173                 // package setting.
11174                 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
11175                 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
11176 
11177                 setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11178 
11179                 if (DEBUG_ABI_SELECTION) {
11180                     Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
11181                         pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
11182                         pkg.applicationInfo.secondaryCpuAbi);
11183                 }
11184             }
11185         } else {
11186             if ((scanFlags & SCAN_MOVE) != 0) {
11187                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
11188                 // but we already have this packages package info in the PackageSetting. We just
11189                 // use that and derive the native library path based on the new codepath.
11190                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
11191                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
11192             }
11193 
11194             // Set native library paths again. For moves, the path will be updated based on the
11195             // ABIs we've determined above. For non-moves, the path will be updated based on the
11196             // ABIs we determined during compilation, but the path will depend on the final
11197             // package path (after the rename away from the stage path).
11198             setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11199         }
11200 
11201         // This is a special case for the "system" package, where the ABI is
11202         // dictated by the zygote configuration (and init.rc). We should keep track
11203         // of this ABI so that we can deal with "normal" applications that run under
11204         // the same UID correctly.
11205         if (mPlatformPackage == pkg) {
11206             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
11207                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
11208         }
11209 
11210         // If there's a mismatch between the abi-override in the package setting
11211         // and the abiOverride specified for the install. Warn about this because we
11212         // would've already compiled the app without taking the package setting into
11213         // account.
11214         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
11215             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
11216                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
11217                         " for package " + pkg.packageName);
11218             }
11219         }
11220 
11221         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11222         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11223         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
11224 
11225         // Copy the derived override back to the parsed package, so that we can
11226         // update the package settings accordingly.
11227         pkg.cpuAbiOverride = cpuAbiOverride;
11228 
11229         if (DEBUG_ABI_SELECTION) {
11230             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
11231                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
11232                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
11233         }
11234 
11235         // Push the derived path down into PackageSettings so we know what to
11236         // clean up at uninstall time.
11237         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
11238 
11239         if (DEBUG_ABI_SELECTION) {
11240             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
11241                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
11242                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
11243         }
11244 
11245         // SIDE EFFECTS; removes DEX files from disk; move elsewhere
11246         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
11247             // We don't do this here during boot because we can do it all
11248             // at once after scanning all existing packages.
11249             //
11250             // We also do this *before* we perform dexopt on this package, so that
11251             // we can avoid redundant dexopts, and also to make sure we've got the
11252             // code and package path correct.
11253             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
11254         }
11255 
11256         if (mFactoryTest && pkg.requestedPermissions.contains(
11257                 android.Manifest.permission.FACTORY_TEST)) {
11258             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
11259         }
11260 
11261         if (isSystemApp(pkg)) {
11262             pkgSetting.isOrphaned = true;
11263         }
11264 
11265         // Take care of first install / last update times.
11266         final long scanFileTime = getLastModifiedTime(pkg, scanFile);
11267         if (currentTime != 0) {
11268             if (pkgSetting.firstInstallTime == 0) {
11269                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11270             } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11271                 pkgSetting.lastUpdateTime = currentTime;
11272             }
11273         } else if (pkgSetting.firstInstallTime == 0) {
11274             // We need *something*.  Take time time stamp of the file.
11275             pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11276         } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11277             if (scanFileTime != pkgSetting.timeStamp) {
11278                 // A package on the system image has changed; consider this
11279                 // to be an update.
11280                 pkgSetting.lastUpdateTime = scanFileTime;
11281             }
11282         }
11283         pkgSetting.setTimeStamp(scanFileTime);
11284 
11285         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
11286             if (nonMutatedPs != null) {
11287                 synchronized (mPackages) {
11288                     mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
11289                 }
11290             }
11291         } else {
11292             final int userId = user == null ? 0 : user.getIdentifier();
11293             // Modify state for the given package setting
11294             commitPackageSettings(pkg, pkgSetting, user, scanFlags,
11295                     (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
11296             if (pkgSetting.getInstantApp(userId)) {
11297                 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
11298             }
11299         }
11300 
11301         if (oldPkg != null) {
11302             // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11303             // revokation from this method might need to kill apps which need the
11304             // mPackages lock on a different thread. This would dead lock.
11305             //
11306             // Hence create a copy of all package names and pass it into
11307             // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11308             // revoked. If a new package is added before the async code runs the permission
11309             // won't be granted yet, hence new packages are no problem.
11310             final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11311 
11312             AsyncTask.execute(new Runnable() {
11313                 public void run() {
11314                     revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames);
11315                 }
11316             });
11317         }
11318 
11319         return pkg;
11320     }
11321 
11322     /**
11323      * Applies policy to the parsed package based upon the given policy flags.
11324      * Ensures the package is in a good state.
11325      * <p>
11326      * Implementation detail: This method must NOT have any side effect. It would
11327      * ideally be static, but, it requires locks to read system state.
11328      */
applyPolicy(PackageParser.Package pkg, int policyFlags)11329     private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
11330         if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
11331             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
11332             if (pkg.applicationInfo.isDirectBootAware()) {
11333                 // we're direct boot aware; set for all components
11334                 for (PackageParser.Service s : pkg.services) {
11335                     s.info.encryptionAware = s.info.directBootAware = true;
11336                 }
11337                 for (PackageParser.Provider p : pkg.providers) {
11338                     p.info.encryptionAware = p.info.directBootAware = true;
11339                 }
11340                 for (PackageParser.Activity a : pkg.activities) {
11341                     a.info.encryptionAware = a.info.directBootAware = true;
11342                 }
11343                 for (PackageParser.Activity r : pkg.receivers) {
11344                     r.info.encryptionAware = r.info.directBootAware = true;
11345                 }
11346             }
11347             if (compressedFileExists(pkg.codePath)) {
11348                 pkg.isStub = true;
11349             }
11350         } else {
11351             // Only allow system apps to be flagged as core apps.
11352             pkg.coreApp = false;
11353             // clear flags not applicable to regular apps
11354             pkg.applicationInfo.privateFlags &=
11355                     ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
11356             pkg.applicationInfo.privateFlags &=
11357                     ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
11358         }
11359         pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
11360 
11361         if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
11362             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
11363         }
11364 
11365         if (!isSystemApp(pkg)) {
11366             // Only system apps can use these features.
11367             pkg.mOriginalPackages = null;
11368             pkg.mRealPackage = null;
11369             pkg.mAdoptPermissions = null;
11370         }
11371     }
11372 
11373     /**
11374      * Asserts the parsed package is valid according to the given policy. If the
11375      * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11376      * <p>
11377      * Implementation detail: This method must NOT have any side effects. It would
11378      * ideally be static, but, it requires locks to read system state.
11379      *
11380      * @throws PackageManagerException If the package fails any of the validation checks
11381      */
assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)11382     private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
11383             throws PackageManagerException {
11384         if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11385             assertCodePolicy(pkg);
11386         }
11387 
11388         if (pkg.applicationInfo.getCodePath() == null ||
11389                 pkg.applicationInfo.getResourcePath() == null) {
11390             // Bail out. The resource and code paths haven't been set.
11391             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11392                     "Code and resource paths haven't been set correctly");
11393         }
11394 
11395         // Make sure we're not adding any bogus keyset info
11396         KeySetManagerService ksms = mSettings.mKeySetManagerService;
11397         ksms.assertScannedPackageValid(pkg);
11398 
11399         synchronized (mPackages) {
11400             // The special "android" package can only be defined once
11401             if (pkg.packageName.equals("android")) {
11402                 if (mAndroidApplication != null) {
11403                     Slog.w(TAG, "*************************************************");
11404                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
11405                     Slog.w(TAG, " codePath=" + pkg.codePath);
11406                     Slog.w(TAG, "*************************************************");
11407                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11408                             "Core android package being redefined.  Skipping.");
11409                 }
11410             }
11411 
11412             // A package name must be unique; don't allow duplicates
11413             if (mPackages.containsKey(pkg.packageName)) {
11414                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11415                         "Application package " + pkg.packageName
11416                         + " already installed.  Skipping duplicate.");
11417             }
11418 
11419             if (pkg.applicationInfo.isStaticSharedLibrary()) {
11420                 // Static libs have a synthetic package name containing the version
11421                 // but we still want the base name to be unique.
11422                 if (mPackages.containsKey(pkg.manifestPackageName)) {
11423                     throw new PackageManagerException(
11424                             "Duplicate static shared lib provider package");
11425                 }
11426 
11427                 // Static shared libraries should have at least O target SDK
11428                 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11429                     throw new PackageManagerException(
11430                             "Packages declaring static-shared libs must target O SDK or higher");
11431                 }
11432 
11433                 // Package declaring static a shared lib cannot be instant apps
11434                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11435                     throw new PackageManagerException(
11436                             "Packages declaring static-shared libs cannot be instant apps");
11437                 }
11438 
11439                 // Package declaring static a shared lib cannot be renamed since the package
11440                 // name is synthetic and apps can't code around package manager internals.
11441                 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11442                     throw new PackageManagerException(
11443                             "Packages declaring static-shared libs cannot be renamed");
11444                 }
11445 
11446                 // Package declaring static a shared lib cannot declare child packages
11447                 if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11448                     throw new PackageManagerException(
11449                             "Packages declaring static-shared libs cannot have child packages");
11450                 }
11451 
11452                 // Package declaring static a shared lib cannot declare dynamic libs
11453                 if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11454                     throw new PackageManagerException(
11455                             "Packages declaring static-shared libs cannot declare dynamic libs");
11456                 }
11457 
11458                 // Package declaring static a shared lib cannot declare shared users
11459                 if (pkg.mSharedUserId != null) {
11460                     throw new PackageManagerException(
11461                             "Packages declaring static-shared libs cannot declare shared users");
11462                 }
11463 
11464                 // Static shared libs cannot declare activities
11465                 if (!pkg.activities.isEmpty()) {
11466                     throw new PackageManagerException(
11467                             "Static shared libs cannot declare activities");
11468                 }
11469 
11470                 // Static shared libs cannot declare services
11471                 if (!pkg.services.isEmpty()) {
11472                     throw new PackageManagerException(
11473                             "Static shared libs cannot declare services");
11474                 }
11475 
11476                 // Static shared libs cannot declare providers
11477                 if (!pkg.providers.isEmpty()) {
11478                     throw new PackageManagerException(
11479                             "Static shared libs cannot declare content providers");
11480                 }
11481 
11482                 // Static shared libs cannot declare receivers
11483                 if (!pkg.receivers.isEmpty()) {
11484                     throw new PackageManagerException(
11485                             "Static shared libs cannot declare broadcast receivers");
11486                 }
11487 
11488                 // Static shared libs cannot declare permission groups
11489                 if (!pkg.permissionGroups.isEmpty()) {
11490                     throw new PackageManagerException(
11491                             "Static shared libs cannot declare permission groups");
11492                 }
11493 
11494                 // Static shared libs cannot declare permissions
11495                 if (!pkg.permissions.isEmpty()) {
11496                     throw new PackageManagerException(
11497                             "Static shared libs cannot declare permissions");
11498                 }
11499 
11500                 // Static shared libs cannot declare protected broadcasts
11501                 if (pkg.protectedBroadcasts != null) {
11502                     throw new PackageManagerException(
11503                             "Static shared libs cannot declare protected broadcasts");
11504                 }
11505 
11506                 // Static shared libs cannot be overlay targets
11507                 if (pkg.mOverlayTarget != null) {
11508                     throw new PackageManagerException(
11509                             "Static shared libs cannot be overlay targets");
11510                 }
11511 
11512                 // The version codes must be ordered as lib versions
11513                 int minVersionCode = Integer.MIN_VALUE;
11514                 int maxVersionCode = Integer.MAX_VALUE;
11515 
11516                 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11517                         pkg.staticSharedLibName);
11518                 if (versionedLib != null) {
11519                     final int versionCount = versionedLib.size();
11520                     for (int i = 0; i < versionCount; i++) {
11521                         SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11522                         final int libVersionCode = libInfo.getDeclaringPackage()
11523                                 .getVersionCode();
11524                         if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
11525                             minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11526                         } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
11527                             maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11528                         } else {
11529                             minVersionCode = maxVersionCode = libVersionCode;
11530                             break;
11531                         }
11532                     }
11533                 }
11534                 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
11535                     throw new PackageManagerException("Static shared"
11536                             + " lib version codes must be ordered as lib versions");
11537                 }
11538             }
11539 
11540             // Only privileged apps and updated privileged apps can add child packages.
11541             if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11542                 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
11543                     throw new PackageManagerException("Only privileged apps can add child "
11544                             + "packages. Ignoring package " + pkg.packageName);
11545                 }
11546                 final int childCount = pkg.childPackages.size();
11547                 for (int i = 0; i < childCount; i++) {
11548                     PackageParser.Package childPkg = pkg.childPackages.get(i);
11549                     if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11550                             childPkg.packageName)) {
11551                         throw new PackageManagerException("Can't override child of "
11552                                 + "another disabled app. Ignoring package " + pkg.packageName);
11553                     }
11554                 }
11555             }
11556 
11557             // If we're only installing presumed-existing packages, require that the
11558             // scanned APK is both already known and at the path previously established
11559             // for it.  Previously unknown packages we pick up normally, but if we have an
11560             // a priori expectation about this package's install presence, enforce it.
11561             // With a singular exception for new system packages. When an OTA contains
11562             // a new system package, we allow the codepath to change from a system location
11563             // to the user-installed location. If we don't allow this change, any newer,
11564             // user-installed version of the application will be ignored.
11565             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11566                 if (mExpectingBetter.containsKey(pkg.packageName)) {
11567                     logCriticalInfo(Log.WARN,
11568                             "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11569                 } else {
11570                     PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11571                     if (known != null) {
11572                         if (DEBUG_PACKAGE_SCANNING) {
11573                             Log.d(TAG, "Examining " + pkg.codePath
11574                                     + " and requiring known paths " + known.codePathString
11575                                     + " & " + known.resourcePathString);
11576                         }
11577                         if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11578                                 || !pkg.applicationInfo.getResourcePath().equals(
11579                                         known.resourcePathString)) {
11580                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11581                                     "Application package " + pkg.packageName
11582                                     + " found at " + pkg.applicationInfo.getCodePath()
11583                                     + " but expected at " + known.codePathString
11584                                     + "; ignoring.");
11585                         }
11586                     } else {
11587                         throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11588                                 "Application package " + pkg.packageName
11589                                 + " not found; ignoring.");
11590                     }
11591                 }
11592             }
11593 
11594             // Verify that this new package doesn't have any content providers
11595             // that conflict with existing packages.  Only do this if the
11596             // package isn't already installed, since we don't want to break
11597             // things that are installed.
11598             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11599                 final int N = pkg.providers.size();
11600                 int i;
11601                 for (i=0; i<N; i++) {
11602                     PackageParser.Provider p = pkg.providers.get(i);
11603                     if (p.info.authority != null) {
11604                         String names[] = p.info.authority.split(";");
11605                         for (int j = 0; j < names.length; j++) {
11606                             if (mProvidersByAuthority.containsKey(names[j])) {
11607                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11608                                 final String otherPackageName =
11609                                         ((other != null && other.getComponentName() != null) ?
11610                                                 other.getComponentName().getPackageName() : "?");
11611                                 throw new PackageManagerException(
11612                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
11613                                         "Can't install because provider name " + names[j]
11614                                                 + " (in package " + pkg.applicationInfo.packageName
11615                                                 + ") is already used by " + otherPackageName);
11616                             }
11617                         }
11618                     }
11619                 }
11620             }
11621         }
11622     }
11623 
addSharedLibraryLPw(String path, String apk, String name, int version, int type, String declaringPackageName, int declaringVersionCode)11624     private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
11625             int type, String declaringPackageName, int declaringVersionCode) {
11626         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11627         if (versionedLib == null) {
11628             versionedLib = new SparseArray<>();
11629             mSharedLibraries.put(name, versionedLib);
11630             if (type == SharedLibraryInfo.TYPE_STATIC) {
11631                 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11632             }
11633         } else if (versionedLib.indexOfKey(version) >= 0) {
11634             return false;
11635         }
11636         SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11637                 version, type, declaringPackageName, declaringVersionCode);
11638         versionedLib.put(version, libEntry);
11639         return true;
11640     }
11641 
removeSharedLibraryLPw(String name, int version)11642     private boolean removeSharedLibraryLPw(String name, int version) {
11643         SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11644         if (versionedLib == null) {
11645             return false;
11646         }
11647         final int libIdx = versionedLib.indexOfKey(version);
11648         if (libIdx < 0) {
11649             return false;
11650         }
11651         SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11652         versionedLib.remove(version);
11653         if (versionedLib.size() <= 0) {
11654             mSharedLibraries.remove(name);
11655             if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11656                 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11657                         .getPackageName());
11658             }
11659         }
11660         return true;
11661     }
11662 
11663     /**
11664      * Adds a scanned package to the system. When this method is finished, the package will
11665      * be available for query, resolution, etc...
11666      */
commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting, UserHandle user, int scanFlags, boolean chatty)11667     private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11668             UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
11669         final String pkgName = pkg.packageName;
11670         if (mCustomResolverComponentName != null &&
11671                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11672             setUpCustomResolverActivity(pkg);
11673         }
11674 
11675         if (pkg.packageName.equals("android")) {
11676             synchronized (mPackages) {
11677                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11678                     // Set up information for our fall-back user intent resolution activity.
11679                     mPlatformPackage = pkg;
11680                     pkg.mVersionCode = mSdkVersion;
11681                     mAndroidApplication = pkg.applicationInfo;
11682                     if (!mResolverReplaced) {
11683                         mResolveActivity.applicationInfo = mAndroidApplication;
11684                         mResolveActivity.name = ResolverActivity.class.getName();
11685                         mResolveActivity.packageName = mAndroidApplication.packageName;
11686                         mResolveActivity.processName = "system:ui";
11687                         mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11688                         mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11689                         mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11690                         mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11691                         mResolveActivity.exported = true;
11692                         mResolveActivity.enabled = true;
11693                         mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11694                         mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11695                                 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11696                                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
11697                                 | ActivityInfo.CONFIG_ORIENTATION
11698                                 | ActivityInfo.CONFIG_KEYBOARD
11699                                 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11700                         mResolveInfo.activityInfo = mResolveActivity;
11701                         mResolveInfo.priority = 0;
11702                         mResolveInfo.preferredOrder = 0;
11703                         mResolveInfo.match = 0;
11704                         mResolveComponentName = new ComponentName(
11705                                 mAndroidApplication.packageName, mResolveActivity.name);
11706                     }
11707                 }
11708             }
11709         }
11710 
11711         ArrayList<PackageParser.Package> clientLibPkgs = null;
11712         // writer
11713         synchronized (mPackages) {
11714             boolean hasStaticSharedLibs = false;
11715 
11716             // Any app can add new static shared libraries
11717             if (pkg.staticSharedLibName != null) {
11718                 // Static shared libs don't allow renaming as they have synthetic package
11719                 // names to allow install of multiple versions, so use name from manifest.
11720                 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11721                         pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11722                         pkg.manifestPackageName, pkg.mVersionCode)) {
11723                     hasStaticSharedLibs = true;
11724                 } else {
11725                     Slog.w(TAG, "Package " + pkg.packageName + " library "
11726                                 + pkg.staticSharedLibName + " already exists; skipping");
11727                 }
11728                 // Static shared libs cannot be updated once installed since they
11729                 // use synthetic package name which includes the version code, so
11730                 // not need to update other packages's shared lib dependencies.
11731             }
11732 
11733             if (!hasStaticSharedLibs
11734                     && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11735                 // Only system apps can add new dynamic shared libraries.
11736                 if (pkg.libraryNames != null) {
11737                     for (int i = 0; i < pkg.libraryNames.size(); i++) {
11738                         String name = pkg.libraryNames.get(i);
11739                         boolean allowed = false;
11740                         if (pkg.isUpdatedSystemApp()) {
11741                             // New library entries can only be added through the
11742                             // system image.  This is important to get rid of a lot
11743                             // of nasty edge cases: for example if we allowed a non-
11744                             // system update of the app to add a library, then uninstalling
11745                             // the update would make the library go away, and assumptions
11746                             // we made such as through app install filtering would now
11747                             // have allowed apps on the device which aren't compatible
11748                             // with it.  Better to just have the restriction here, be
11749                             // conservative, and create many fewer cases that can negatively
11750                             // impact the user experience.
11751                             final PackageSetting sysPs = mSettings
11752                                     .getDisabledSystemPkgLPr(pkg.packageName);
11753                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11754                                 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11755                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11756                                         allowed = true;
11757                                         break;
11758                                     }
11759                                 }
11760                             }
11761                         } else {
11762                             allowed = true;
11763                         }
11764                         if (allowed) {
11765                             if (!addSharedLibraryLPw(null, pkg.packageName, name,
11766                                     SharedLibraryInfo.VERSION_UNDEFINED,
11767                                     SharedLibraryInfo.TYPE_DYNAMIC,
11768                                     pkg.packageName, pkg.mVersionCode)) {
11769                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
11770                                         + name + " already exists; skipping");
11771                             }
11772                         } else {
11773                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11774                                     + name + " that is not declared on system image; skipping");
11775                         }
11776                     }
11777 
11778                     if ((scanFlags & SCAN_BOOTING) == 0) {
11779                         // If we are not booting, we need to update any applications
11780                         // that are clients of our shared library.  If we are booting,
11781                         // this will all be done once the scan is complete.
11782                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11783                     }
11784                 }
11785             }
11786         }
11787 
11788         if ((scanFlags & SCAN_BOOTING) != 0) {
11789             // No apps can run during boot scan, so they don't need to be frozen
11790         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11791             // Caller asked to not kill app, so it's probably not frozen
11792         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11793             // Caller asked us to ignore frozen check for some reason; they
11794             // probably didn't know the package name
11795         } else {
11796             // We're doing major surgery on this package, so it better be frozen
11797             // right now to keep it from launching
11798             checkPackageFrozen(pkgName);
11799         }
11800 
11801         // Also need to kill any apps that are dependent on the library.
11802         if (clientLibPkgs != null) {
11803             for (int i=0; i<clientLibPkgs.size(); i++) {
11804                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
11805                 killApplication(clientPkg.applicationInfo.packageName,
11806                         clientPkg.applicationInfo.uid, "update lib");
11807             }
11808         }
11809 
11810         // writer
11811         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11812 
11813         synchronized (mPackages) {
11814             // We don't expect installation to fail beyond this point
11815 
11816             // Add the new setting to mSettings
11817             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11818             // Add the new setting to mPackages
11819             mPackages.put(pkg.applicationInfo.packageName, pkg);
11820             // Make sure we don't accidentally delete its data.
11821             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11822             while (iter.hasNext()) {
11823                 PackageCleanItem item = iter.next();
11824                 if (pkgName.equals(item.packageName)) {
11825                     iter.remove();
11826                 }
11827             }
11828 
11829             // Add the package's KeySets to the global KeySetManagerService
11830             KeySetManagerService ksms = mSettings.mKeySetManagerService;
11831             ksms.addScannedPackageLPw(pkg);
11832 
11833             int N = pkg.providers.size();
11834             StringBuilder r = null;
11835             int i;
11836             for (i=0; i<N; i++) {
11837                 PackageParser.Provider p = pkg.providers.get(i);
11838                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11839                         p.info.processName);
11840                 mProviders.addProvider(p);
11841                 p.syncable = p.info.isSyncable;
11842                 if (p.info.authority != null) {
11843                     String names[] = p.info.authority.split(";");
11844                     p.info.authority = null;
11845                     for (int j = 0; j < names.length; j++) {
11846                         if (j == 1 && p.syncable) {
11847                             // We only want the first authority for a provider to possibly be
11848                             // syncable, so if we already added this provider using a different
11849                             // authority clear the syncable flag. We copy the provider before
11850                             // changing it because the mProviders object contains a reference
11851                             // to a provider that we don't want to change.
11852                             // Only do this for the second authority since the resulting provider
11853                             // object can be the same for all future authorities for this provider.
11854                             p = new PackageParser.Provider(p);
11855                             p.syncable = false;
11856                         }
11857                         if (!mProvidersByAuthority.containsKey(names[j])) {
11858                             mProvidersByAuthority.put(names[j], p);
11859                             if (p.info.authority == null) {
11860                                 p.info.authority = names[j];
11861                             } else {
11862                                 p.info.authority = p.info.authority + ";" + names[j];
11863                             }
11864                             if (DEBUG_PACKAGE_SCANNING) {
11865                                 if (chatty)
11866                                     Log.d(TAG, "Registered content provider: " + names[j]
11867                                             + ", className = " + p.info.name + ", isSyncable = "
11868                                             + p.info.isSyncable);
11869                             }
11870                         } else {
11871                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11872                             Slog.w(TAG, "Skipping provider name " + names[j] +
11873                                     " (in package " + pkg.applicationInfo.packageName +
11874                                     "): name already used by "
11875                                     + ((other != null && other.getComponentName() != null)
11876                                             ? other.getComponentName().getPackageName() : "?"));
11877                         }
11878                     }
11879                 }
11880                 if (chatty) {
11881                     if (r == null) {
11882                         r = new StringBuilder(256);
11883                     } else {
11884                         r.append(' ');
11885                     }
11886                     r.append(p.info.name);
11887                 }
11888             }
11889             if (r != null) {
11890                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11891             }
11892 
11893             N = pkg.services.size();
11894             r = null;
11895             for (i=0; i<N; i++) {
11896                 PackageParser.Service s = pkg.services.get(i);
11897                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11898                         s.info.processName);
11899                 mServices.addService(s);
11900                 if (chatty) {
11901                     if (r == null) {
11902                         r = new StringBuilder(256);
11903                     } else {
11904                         r.append(' ');
11905                     }
11906                     r.append(s.info.name);
11907                 }
11908             }
11909             if (r != null) {
11910                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11911             }
11912 
11913             N = pkg.receivers.size();
11914             r = null;
11915             for (i=0; i<N; i++) {
11916                 PackageParser.Activity a = pkg.receivers.get(i);
11917                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11918                         a.info.processName);
11919                 mReceivers.addActivity(a, "receiver");
11920                 if (chatty) {
11921                     if (r == null) {
11922                         r = new StringBuilder(256);
11923                     } else {
11924                         r.append(' ');
11925                     }
11926                     r.append(a.info.name);
11927                 }
11928             }
11929             if (r != null) {
11930                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11931             }
11932 
11933             N = pkg.activities.size();
11934             r = null;
11935             for (i=0; i<N; i++) {
11936                 PackageParser.Activity a = pkg.activities.get(i);
11937                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11938                         a.info.processName);
11939                 mActivities.addActivity(a, "activity");
11940                 if (chatty) {
11941                     if (r == null) {
11942                         r = new StringBuilder(256);
11943                     } else {
11944                         r.append(' ');
11945                     }
11946                     r.append(a.info.name);
11947                 }
11948             }
11949             if (r != null) {
11950                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11951             }
11952 
11953             N = pkg.permissionGroups.size();
11954             r = null;
11955             for (i=0; i<N; i++) {
11956                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11957                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11958                 final String curPackageName = cur == null ? null : cur.info.packageName;
11959                 // Dont allow ephemeral apps to define new permission groups.
11960                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11961                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11962                             + pg.info.packageName
11963                             + " ignored: instant apps cannot define new permission groups.");
11964                     continue;
11965                 }
11966                 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11967                 if (cur == null || isPackageUpdate) {
11968                     mPermissionGroups.put(pg.info.name, pg);
11969                     if (chatty) {
11970                         if (r == null) {
11971                             r = new StringBuilder(256);
11972                         } else {
11973                             r.append(' ');
11974                         }
11975                         if (isPackageUpdate) {
11976                             r.append("UPD:");
11977                         }
11978                         r.append(pg.info.name);
11979                     }
11980                 } else {
11981                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11982                             + pg.info.packageName + " ignored: original from "
11983                             + cur.info.packageName);
11984                     if (chatty) {
11985                         if (r == null) {
11986                             r = new StringBuilder(256);
11987                         } else {
11988                             r.append(' ');
11989                         }
11990                         r.append("DUP:");
11991                         r.append(pg.info.name);
11992                     }
11993                 }
11994             }
11995             if (r != null) {
11996                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11997             }
11998 
11999             N = pkg.permissions.size();
12000             r = null;
12001             for (i=0; i<N; i++) {
12002                 PackageParser.Permission p = pkg.permissions.get(i);
12003 
12004                 // Dont allow ephemeral apps to define new permissions.
12005                 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
12006                     Slog.w(TAG, "Permission " + p.info.name + " from package "
12007                             + p.info.packageName
12008                             + " ignored: instant apps cannot define new permissions.");
12009                     continue;
12010                 }
12011 
12012                 // Assume by default that we did not install this permission into the system.
12013                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
12014 
12015                 // Now that permission groups have a special meaning, we ignore permission
12016                 // groups for legacy apps to prevent unexpected behavior. In particular,
12017                 // permissions for one app being granted to someone just because they happen
12018                 // to be in a group defined by another app (before this had no implications).
12019                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
12020                     p.group = mPermissionGroups.get(p.info.group);
12021                     // Warn for a permission in an unknown group.
12022                     if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
12023                         Slog.i(TAG, "Permission " + p.info.name + " from package "
12024                                 + p.info.packageName + " in an unknown group " + p.info.group);
12025                     }
12026                 }
12027 
12028                 ArrayMap<String, BasePermission> permissionMap =
12029                         p.tree ? mSettings.mPermissionTrees
12030                                 : mSettings.mPermissions;
12031                 BasePermission bp = permissionMap.get(p.info.name);
12032 
12033                 // Allow system apps to redefine non-system permissions
12034                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
12035                     final boolean currentOwnerIsSystem = (bp.perm != null
12036                             && isSystemApp(bp.perm.owner));
12037                     if (isSystemApp(p.owner)) {
12038                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
12039                             // It's a built-in permission and no owner, take ownership now
12040                             bp.packageSetting = pkgSetting;
12041                             bp.perm = p;
12042                             bp.uid = pkg.applicationInfo.uid;
12043                             bp.sourcePackage = p.info.packageName;
12044                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
12045                         } else if (!currentOwnerIsSystem) {
12046                             String msg = "New decl " + p.owner + " of permission  "
12047                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
12048                             reportSettingsProblem(Log.WARN, msg);
12049                             bp = null;
12050                         }
12051                     }
12052                 }
12053 
12054                 if (bp == null) {
12055                     bp = new BasePermission(p.info.name, p.info.packageName,
12056                             BasePermission.TYPE_NORMAL);
12057                     permissionMap.put(p.info.name, bp);
12058                 }
12059 
12060                 if (bp.perm == null) {
12061                     if (bp.sourcePackage == null
12062                             || bp.sourcePackage.equals(p.info.packageName)) {
12063                         BasePermission tree = findPermissionTreeLP(p.info.name);
12064                         if (tree == null
12065                                 || tree.sourcePackage.equals(p.info.packageName)) {
12066                             bp.packageSetting = pkgSetting;
12067                             bp.perm = p;
12068                             bp.uid = pkg.applicationInfo.uid;
12069                             bp.sourcePackage = p.info.packageName;
12070                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
12071                             if (chatty) {
12072                                 if (r == null) {
12073                                     r = new StringBuilder(256);
12074                                 } else {
12075                                     r.append(' ');
12076                                 }
12077                                 r.append(p.info.name);
12078                             }
12079                         } else {
12080                             Slog.w(TAG, "Permission " + p.info.name + " from package "
12081                                     + p.info.packageName + " ignored: base tree "
12082                                     + tree.name + " is from package "
12083                                     + tree.sourcePackage);
12084                         }
12085                     } else {
12086                         Slog.w(TAG, "Permission " + p.info.name + " from package "
12087                                 + p.info.packageName + " ignored: original from "
12088                                 + bp.sourcePackage);
12089                     }
12090                 } else if (chatty) {
12091                     if (r == null) {
12092                         r = new StringBuilder(256);
12093                     } else {
12094                         r.append(' ');
12095                     }
12096                     r.append("DUP:");
12097                     r.append(p.info.name);
12098                 }
12099                 if (bp.perm == p) {
12100                     bp.protectionLevel = p.info.protectionLevel;
12101                 }
12102             }
12103 
12104             if (r != null) {
12105                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
12106             }
12107 
12108             N = pkg.instrumentation.size();
12109             r = null;
12110             for (i=0; i<N; i++) {
12111                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12112                 a.info.packageName = pkg.applicationInfo.packageName;
12113                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
12114                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
12115                 a.info.splitNames = pkg.splitNames;
12116                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
12117                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
12118                 a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
12119                 a.info.dataDir = pkg.applicationInfo.dataDir;
12120                 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
12121                 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
12122                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
12123                 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
12124                 mInstrumentation.put(a.getComponentName(), a);
12125                 if (chatty) {
12126                     if (r == null) {
12127                         r = new StringBuilder(256);
12128                     } else {
12129                         r.append(' ');
12130                     }
12131                     r.append(a.info.name);
12132                 }
12133             }
12134             if (r != null) {
12135                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
12136             }
12137 
12138             if (pkg.protectedBroadcasts != null) {
12139                 N = pkg.protectedBroadcasts.size();
12140                 synchronized (mProtectedBroadcasts) {
12141                     for (i = 0; i < N; i++) {
12142                         mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
12143                     }
12144                 }
12145             }
12146         }
12147 
12148         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12149     }
12150 
12151     /**
12152      * Derive the ABI of a non-system package located at {@code scanFile}. This information
12153      * is derived purely on the basis of the contents of {@code scanFile} and
12154      * {@code cpuAbiOverride}.
12155      *
12156      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
12157      */
derivePackageAbi(PackageParser.Package pkg, File scanFile, String cpuAbiOverride, boolean extractLibs, File appLib32InstallDir)12158     private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
12159                                  String cpuAbiOverride, boolean extractLibs,
12160                                  File appLib32InstallDir)
12161             throws PackageManagerException {
12162         // Give ourselves some initial paths; we'll come back for another
12163         // pass once we've determined ABI below.
12164         setNativeLibraryPaths(pkg, appLib32InstallDir);
12165 
12166         // We would never need to extract libs for forward-locked and external packages,
12167         // since the container service will do it for us. We shouldn't attempt to
12168         // extract libs from system app when it was not updated.
12169         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
12170                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
12171             extractLibs = false;
12172         }
12173 
12174         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
12175         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
12176 
12177         NativeLibraryHelper.Handle handle = null;
12178         try {
12179             handle = NativeLibraryHelper.Handle.create(pkg);
12180             // TODO(multiArch): This can be null for apps that didn't go through the
12181             // usual installation process. We can calculate it again, like we
12182             // do during install time.
12183             //
12184             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
12185             // unnecessary.
12186             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
12187 
12188             // Null out the abis so that they can be recalculated.
12189             pkg.applicationInfo.primaryCpuAbi = null;
12190             pkg.applicationInfo.secondaryCpuAbi = null;
12191             if (isMultiArch(pkg.applicationInfo)) {
12192                 // Warn if we've set an abiOverride for multi-lib packages..
12193                 // By definition, we need to copy both 32 and 64 bit libraries for
12194                 // such packages.
12195                 if (pkg.cpuAbiOverride != null
12196                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
12197                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
12198                 }
12199 
12200                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
12201                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
12202                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
12203                     if (extractLibs) {
12204                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12205                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12206                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
12207                                 useIsaSpecificSubdirs);
12208                     } else {
12209                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12210                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
12211                     }
12212                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12213                 }
12214 
12215                 // Shared library native code should be in the APK zip aligned
12216                 if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
12217                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12218                             "Shared library native lib extraction not supported");
12219                 }
12220 
12221                 maybeThrowExceptionForMultiArchCopy(
12222                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
12223 
12224                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
12225                     if (extractLibs) {
12226                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12227                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12228                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
12229                                 useIsaSpecificSubdirs);
12230                     } else {
12231                         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12232                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
12233                     }
12234                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12235                 }
12236 
12237                 maybeThrowExceptionForMultiArchCopy(
12238                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
12239 
12240                 if (abi64 >= 0) {
12241                     // Shared library native libs should be in the APK zip aligned
12242                     if (extractLibs && pkg.isLibrary()) {
12243                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12244                                 "Shared library native lib extraction not supported");
12245                     }
12246                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
12247                 }
12248 
12249                 if (abi32 >= 0) {
12250                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
12251                     if (abi64 >= 0) {
12252                         if (pkg.use32bitAbi) {
12253                             pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
12254                             pkg.applicationInfo.primaryCpuAbi = abi;
12255                         } else {
12256                             pkg.applicationInfo.secondaryCpuAbi = abi;
12257                         }
12258                     } else {
12259                         pkg.applicationInfo.primaryCpuAbi = abi;
12260                     }
12261                 }
12262             } else {
12263                 String[] abiList = (cpuAbiOverride != null) ?
12264                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
12265 
12266                 // Enable gross and lame hacks for apps that are built with old
12267                 // SDK tools. We must scan their APKs for renderscript bitcode and
12268                 // not launch them if it's present. Don't bother checking on devices
12269                 // that don't have 64 bit support.
12270                 boolean needsRenderScriptOverride = false;
12271                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
12272                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
12273                     abiList = Build.SUPPORTED_32_BIT_ABIS;
12274                     needsRenderScriptOverride = true;
12275                 }
12276 
12277                 final int copyRet;
12278                 if (extractLibs) {
12279                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12280                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12281                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
12282                 } else {
12283                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12284                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
12285                 }
12286                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12287 
12288                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
12289                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12290                             "Error unpackaging native libs for app, errorCode=" + copyRet);
12291                 }
12292 
12293                 if (copyRet >= 0) {
12294                     // Shared libraries that have native libs must be multi-architecture
12295                     if (pkg.isLibrary()) {
12296                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12297                                 "Shared library with native libs must be multiarch");
12298                     }
12299                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
12300                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
12301                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
12302                 } else if (needsRenderScriptOverride) {
12303                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
12304                 }
12305             }
12306         } catch (IOException ioe) {
12307             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
12308         } finally {
12309             IoUtils.closeQuietly(handle);
12310         }
12311 
12312         // Now that we've calculated the ABIs and determined if it's an internal app,
12313         // we will go ahead and populate the nativeLibraryPath.
12314         setNativeLibraryPaths(pkg, appLib32InstallDir);
12315     }
12316 
12317     /**
12318      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
12319      * i.e, so that all packages can be run inside a single process if required.
12320      *
12321      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
12322      * this function will either try and make the ABI for all packages in {@code packagesForUser}
12323      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
12324      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
12325      * updating a package that belongs to a shared user.
12326      *
12327      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
12328      * adds unnecessary complexity.
12329      */
adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage)12330     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
12331             PackageParser.Package scannedPackage) {
12332         String requiredInstructionSet = null;
12333         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
12334             requiredInstructionSet = VMRuntime.getInstructionSet(
12335                      scannedPackage.applicationInfo.primaryCpuAbi);
12336         }
12337 
12338         PackageSetting requirer = null;
12339         for (PackageSetting ps : packagesForUser) {
12340             // If packagesForUser contains scannedPackage, we skip it. This will happen
12341             // when scannedPackage is an update of an existing package. Without this check,
12342             // we will never be able to change the ABI of any package belonging to a shared
12343             // user, even if it's compatible with other packages.
12344             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12345                 if (ps.primaryCpuAbiString == null) {
12346                     continue;
12347                 }
12348 
12349                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
12350                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
12351                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
12352                     // this but there's not much we can do.
12353                     String errorMessage = "Instruction set mismatch, "
12354                             + ((requirer == null) ? "[caller]" : requirer)
12355                             + " requires " + requiredInstructionSet + " whereas " + ps
12356                             + " requires " + instructionSet;
12357                     Slog.w(TAG, errorMessage);
12358                 }
12359 
12360                 if (requiredInstructionSet == null) {
12361                     requiredInstructionSet = instructionSet;
12362                     requirer = ps;
12363                 }
12364             }
12365         }
12366 
12367         if (requiredInstructionSet != null) {
12368             String adjustedAbi;
12369             if (requirer != null) {
12370                 // requirer != null implies that either scannedPackage was null or that scannedPackage
12371                 // did not require an ABI, in which case we have to adjust scannedPackage to match
12372                 // the ABI of the set (which is the same as requirer's ABI)
12373                 adjustedAbi = requirer.primaryCpuAbiString;
12374                 if (scannedPackage != null) {
12375                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
12376                 }
12377             } else {
12378                 // requirer == null implies that we're updating all ABIs in the set to
12379                 // match scannedPackage.
12380                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
12381             }
12382 
12383             for (PackageSetting ps : packagesForUser) {
12384                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12385                     if (ps.primaryCpuAbiString != null) {
12386                         continue;
12387                     }
12388 
12389                     ps.primaryCpuAbiString = adjustedAbi;
12390                     if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12391                             !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12392                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12393                         if (DEBUG_ABI_SELECTION) {
12394                             Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12395                                     + " (requirer="
12396                                     + (requirer != null ? requirer.pkg : "null")
12397                                     + ", scannedPackage="
12398                                     + (scannedPackage != null ? scannedPackage : "null")
12399                                     + ")");
12400                         }
12401                         try {
12402                             mInstaller.rmdex(ps.codePathString,
12403                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
12404                         } catch (InstallerException ignored) {
12405                         }
12406                     }
12407                 }
12408             }
12409         }
12410     }
12411 
setUpCustomResolverActivity(PackageParser.Package pkg)12412     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12413         synchronized (mPackages) {
12414             mResolverReplaced = true;
12415             // Set up information for custom user intent resolution activity.
12416             mResolveActivity.applicationInfo = pkg.applicationInfo;
12417             mResolveActivity.name = mCustomResolverComponentName.getClassName();
12418             mResolveActivity.packageName = pkg.applicationInfo.packageName;
12419             mResolveActivity.processName = pkg.applicationInfo.packageName;
12420             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12421             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12422                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12423             mResolveActivity.theme = 0;
12424             mResolveActivity.exported = true;
12425             mResolveActivity.enabled = true;
12426             mResolveInfo.activityInfo = mResolveActivity;
12427             mResolveInfo.priority = 0;
12428             mResolveInfo.preferredOrder = 0;
12429             mResolveInfo.match = 0;
12430             mResolveComponentName = mCustomResolverComponentName;
12431             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12432                     mResolveComponentName);
12433         }
12434     }
12435 
setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity)12436     private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12437         if (installerActivity == null) {
12438             if (DEBUG_EPHEMERAL) {
12439                 Slog.d(TAG, "Clear ephemeral installer activity");
12440             }
12441             mInstantAppInstallerActivity = null;
12442             return;
12443         }
12444 
12445         if (DEBUG_EPHEMERAL) {
12446             Slog.d(TAG, "Set ephemeral installer activity: "
12447                     + installerActivity.getComponentName());
12448         }
12449         // Set up information for ephemeral installer activity
12450         mInstantAppInstallerActivity = installerActivity;
12451         mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12452                 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12453         mInstantAppInstallerActivity.exported = true;
12454         mInstantAppInstallerActivity.enabled = true;
12455         mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12456         mInstantAppInstallerInfo.priority = 0;
12457         mInstantAppInstallerInfo.preferredOrder = 1;
12458         mInstantAppInstallerInfo.isDefault = true;
12459         mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12460                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12461     }
12462 
calculateBundledApkRoot(final String codePathString)12463     private static String calculateBundledApkRoot(final String codePathString) {
12464         final File codePath = new File(codePathString);
12465         final File codeRoot;
12466         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12467             codeRoot = Environment.getRootDirectory();
12468         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12469             codeRoot = Environment.getOemDirectory();
12470         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12471             codeRoot = Environment.getVendorDirectory();
12472         } else {
12473             // Unrecognized code path; take its top real segment as the apk root:
12474             // e.g. /something/app/blah.apk => /something
12475             try {
12476                 File f = codePath.getCanonicalFile();
12477                 File parent = f.getParentFile();    // non-null because codePath is a file
12478                 File tmp;
12479                 while ((tmp = parent.getParentFile()) != null) {
12480                     f = parent;
12481                     parent = tmp;
12482                 }
12483                 codeRoot = f;
12484                 Slog.w(TAG, "Unrecognized code path "
12485                         + codePath + " - using " + codeRoot);
12486             } catch (IOException e) {
12487                 // Can't canonicalize the code path -- shenanigans?
12488                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
12489                 return Environment.getRootDirectory().getPath();
12490             }
12491         }
12492         return codeRoot.getPath();
12493     }
12494 
12495     /**
12496      * Derive and set the location of native libraries for the given package,
12497      * which varies depending on where and how the package was installed.
12498      */
setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir)12499     private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12500         final ApplicationInfo info = pkg.applicationInfo;
12501         final String codePath = pkg.codePath;
12502         final File codeFile = new File(codePath);
12503         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12504         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12505 
12506         info.nativeLibraryRootDir = null;
12507         info.nativeLibraryRootRequiresIsa = false;
12508         info.nativeLibraryDir = null;
12509         info.secondaryNativeLibraryDir = null;
12510 
12511         if (isApkFile(codeFile)) {
12512             // Monolithic install
12513             if (bundledApp) {
12514                 // If "/system/lib64/apkname" exists, assume that is the per-package
12515                 // native library directory to use; otherwise use "/system/lib/apkname".
12516                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12517                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12518                         getPrimaryInstructionSet(info));
12519 
12520                 // This is a bundled system app so choose the path based on the ABI.
12521                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12522                 // is just the default path.
12523                 final String apkName = deriveCodePathName(codePath);
12524                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12525                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12526                         apkName).getAbsolutePath();
12527 
12528                 if (info.secondaryCpuAbi != null) {
12529                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12530                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12531                             secondaryLibDir, apkName).getAbsolutePath();
12532                 }
12533             } else if (asecApp) {
12534                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12535                         .getAbsolutePath();
12536             } else {
12537                 final String apkName = deriveCodePathName(codePath);
12538                 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12539                         .getAbsolutePath();
12540             }
12541 
12542             info.nativeLibraryRootRequiresIsa = false;
12543             info.nativeLibraryDir = info.nativeLibraryRootDir;
12544         } else {
12545             // Cluster install
12546             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12547             info.nativeLibraryRootRequiresIsa = true;
12548 
12549             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12550                     getPrimaryInstructionSet(info)).getAbsolutePath();
12551 
12552             if (info.secondaryCpuAbi != null) {
12553                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12554                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12555             }
12556         }
12557     }
12558 
12559     /**
12560      * Calculate the abis and roots for a bundled app. These can uniquely
12561      * be determined from the contents of the system partition, i.e whether
12562      * it contains 64 or 32 bit shared libraries etc. We do not validate any
12563      * of this information, and instead assume that the system was built
12564      * sensibly.
12565      */
setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)12566     private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12567                                            PackageSetting pkgSetting) {
12568         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12569 
12570         // If "/system/lib64/apkname" exists, assume that is the per-package
12571         // native library directory to use; otherwise use "/system/lib/apkname".
12572         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12573         setBundledAppAbi(pkg, apkRoot, apkName);
12574         // pkgSetting might be null during rescan following uninstall of updates
12575         // to a bundled app, so accommodate that possibility.  The settings in
12576         // that case will be established later from the parsed package.
12577         //
12578         // If the settings aren't null, sync them up with what we've just derived.
12579         // note that apkRoot isn't stored in the package settings.
12580         if (pkgSetting != null) {
12581             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12582             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12583         }
12584     }
12585 
12586     /**
12587      * Deduces the ABI of a bundled app and sets the relevant fields on the
12588      * parsed pkg object.
12589      *
12590      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12591      *        under which system libraries are installed.
12592      * @param apkName the name of the installed package.
12593      */
setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName)12594     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12595         final File codeFile = new File(pkg.codePath);
12596 
12597         final boolean has64BitLibs;
12598         final boolean has32BitLibs;
12599         if (isApkFile(codeFile)) {
12600             // Monolithic install
12601             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12602             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12603         } else {
12604             // Cluster install
12605             final File rootDir = new File(codeFile, LIB_DIR_NAME);
12606             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12607                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12608                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12609                 has64BitLibs = (new File(rootDir, isa)).exists();
12610             } else {
12611                 has64BitLibs = false;
12612             }
12613             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12614                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12615                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12616                 has32BitLibs = (new File(rootDir, isa)).exists();
12617             } else {
12618                 has32BitLibs = false;
12619             }
12620         }
12621 
12622         if (has64BitLibs && !has32BitLibs) {
12623             // The package has 64 bit libs, but not 32 bit libs. Its primary
12624             // ABI should be 64 bit. We can safely assume here that the bundled
12625             // native libraries correspond to the most preferred ABI in the list.
12626 
12627             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12628             pkg.applicationInfo.secondaryCpuAbi = null;
12629         } else if (has32BitLibs && !has64BitLibs) {
12630             // The package has 32 bit libs but not 64 bit libs. Its primary
12631             // ABI should be 32 bit.
12632 
12633             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12634             pkg.applicationInfo.secondaryCpuAbi = null;
12635         } else if (has32BitLibs && has64BitLibs) {
12636             // The application has both 64 and 32 bit bundled libraries. We check
12637             // here that the app declares multiArch support, and warn if it doesn't.
12638             //
12639             // We will be lenient here and record both ABIs. The primary will be the
12640             // ABI that's higher on the list, i.e, a device that's configured to prefer
12641             // 64 bit apps will see a 64 bit primary ABI,
12642 
12643             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12644                 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12645             }
12646 
12647             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12648                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12649                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12650             } else {
12651                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12652                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12653             }
12654         } else {
12655             pkg.applicationInfo.primaryCpuAbi = null;
12656             pkg.applicationInfo.secondaryCpuAbi = null;
12657         }
12658     }
12659 
killApplication(String pkgName, int appId, String reason)12660     private void killApplication(String pkgName, int appId, String reason) {
12661         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12662     }
12663 
killApplication(String pkgName, int appId, int userId, String reason)12664     private void killApplication(String pkgName, int appId, int userId, String reason) {
12665         // Request the ActivityManager to kill the process(only for existing packages)
12666         // so that we do not end up in a confused state while the user is still using the older
12667         // version of the application while the new one gets installed.
12668         final long token = Binder.clearCallingIdentity();
12669         try {
12670             IActivityManager am = ActivityManager.getService();
12671             if (am != null) {
12672                 try {
12673                     am.killApplication(pkgName, appId, userId, reason);
12674                 } catch (RemoteException e) {
12675                 }
12676             }
12677         } finally {
12678             Binder.restoreCallingIdentity(token);
12679         }
12680     }
12681 
removePackageLI(PackageParser.Package pkg, boolean chatty)12682     private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12683         // Remove the parent package setting
12684         PackageSetting ps = (PackageSetting) pkg.mExtras;
12685         if (ps != null) {
12686             removePackageLI(ps, chatty);
12687         }
12688         // Remove the child package setting
12689         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12690         for (int i = 0; i < childCount; i++) {
12691             PackageParser.Package childPkg = pkg.childPackages.get(i);
12692             ps = (PackageSetting) childPkg.mExtras;
12693             if (ps != null) {
12694                 removePackageLI(ps, chatty);
12695             }
12696         }
12697     }
12698 
removePackageLI(PackageSetting ps, boolean chatty)12699     void removePackageLI(PackageSetting ps, boolean chatty) {
12700         if (DEBUG_INSTALL) {
12701             if (chatty)
12702                 Log.d(TAG, "Removing package " + ps.name);
12703         }
12704 
12705         // writer
12706         synchronized (mPackages) {
12707             mPackages.remove(ps.name);
12708             final PackageParser.Package pkg = ps.pkg;
12709             if (pkg != null) {
12710                 cleanPackageDataStructuresLILPw(pkg, chatty);
12711             }
12712         }
12713     }
12714 
removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)12715     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12716         if (DEBUG_INSTALL) {
12717             if (chatty)
12718                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12719         }
12720 
12721         // writer
12722         synchronized (mPackages) {
12723             // Remove the parent package
12724             mPackages.remove(pkg.applicationInfo.packageName);
12725             cleanPackageDataStructuresLILPw(pkg, chatty);
12726 
12727             // Remove the child packages
12728             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12729             for (int i = 0; i < childCount; i++) {
12730                 PackageParser.Package childPkg = pkg.childPackages.get(i);
12731                 mPackages.remove(childPkg.applicationInfo.packageName);
12732                 cleanPackageDataStructuresLILPw(childPkg, chatty);
12733             }
12734         }
12735     }
12736 
cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)12737     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12738         int N = pkg.providers.size();
12739         StringBuilder r = null;
12740         int i;
12741         for (i=0; i<N; i++) {
12742             PackageParser.Provider p = pkg.providers.get(i);
12743             mProviders.removeProvider(p);
12744             if (p.info.authority == null) {
12745 
12746                 /* There was another ContentProvider with this authority when
12747                  * this app was installed so this authority is null,
12748                  * Ignore it as we don't have to unregister the provider.
12749                  */
12750                 continue;
12751             }
12752             String names[] = p.info.authority.split(";");
12753             for (int j = 0; j < names.length; j++) {
12754                 if (mProvidersByAuthority.get(names[j]) == p) {
12755                     mProvidersByAuthority.remove(names[j]);
12756                     if (DEBUG_REMOVE) {
12757                         if (chatty)
12758                             Log.d(TAG, "Unregistered content provider: " + names[j]
12759                                     + ", className = " + p.info.name + ", isSyncable = "
12760                                     + p.info.isSyncable);
12761                     }
12762                 }
12763             }
12764             if (DEBUG_REMOVE && chatty) {
12765                 if (r == null) {
12766                     r = new StringBuilder(256);
12767                 } else {
12768                     r.append(' ');
12769                 }
12770                 r.append(p.info.name);
12771             }
12772         }
12773         if (r != null) {
12774             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12775         }
12776 
12777         N = pkg.services.size();
12778         r = null;
12779         for (i=0; i<N; i++) {
12780             PackageParser.Service s = pkg.services.get(i);
12781             mServices.removeService(s);
12782             if (chatty) {
12783                 if (r == null) {
12784                     r = new StringBuilder(256);
12785                 } else {
12786                     r.append(' ');
12787                 }
12788                 r.append(s.info.name);
12789             }
12790         }
12791         if (r != null) {
12792             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12793         }
12794 
12795         N = pkg.receivers.size();
12796         r = null;
12797         for (i=0; i<N; i++) {
12798             PackageParser.Activity a = pkg.receivers.get(i);
12799             mReceivers.removeActivity(a, "receiver");
12800             if (DEBUG_REMOVE && chatty) {
12801                 if (r == null) {
12802                     r = new StringBuilder(256);
12803                 } else {
12804                     r.append(' ');
12805                 }
12806                 r.append(a.info.name);
12807             }
12808         }
12809         if (r != null) {
12810             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12811         }
12812 
12813         N = pkg.activities.size();
12814         r = null;
12815         for (i=0; i<N; i++) {
12816             PackageParser.Activity a = pkg.activities.get(i);
12817             mActivities.removeActivity(a, "activity");
12818             if (DEBUG_REMOVE && chatty) {
12819                 if (r == null) {
12820                     r = new StringBuilder(256);
12821                 } else {
12822                     r.append(' ');
12823                 }
12824                 r.append(a.info.name);
12825             }
12826         }
12827         if (r != null) {
12828             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12829         }
12830 
12831         N = pkg.permissions.size();
12832         r = null;
12833         for (i=0; i<N; i++) {
12834             PackageParser.Permission p = pkg.permissions.get(i);
12835             BasePermission bp = mSettings.mPermissions.get(p.info.name);
12836             if (bp == null) {
12837                 bp = mSettings.mPermissionTrees.get(p.info.name);
12838             }
12839             if (bp != null && bp.perm == p) {
12840                 bp.perm = null;
12841                 if (DEBUG_REMOVE && chatty) {
12842                     if (r == null) {
12843                         r = new StringBuilder(256);
12844                     } else {
12845                         r.append(' ');
12846                     }
12847                     r.append(p.info.name);
12848                 }
12849             }
12850             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12851                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12852                 if (appOpPkgs != null) {
12853                     appOpPkgs.remove(pkg.packageName);
12854                 }
12855             }
12856         }
12857         if (r != null) {
12858             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12859         }
12860 
12861         N = pkg.requestedPermissions.size();
12862         r = null;
12863         for (i=0; i<N; i++) {
12864             String perm = pkg.requestedPermissions.get(i);
12865             BasePermission bp = mSettings.mPermissions.get(perm);
12866             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12867                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12868                 if (appOpPkgs != null) {
12869                     appOpPkgs.remove(pkg.packageName);
12870                     if (appOpPkgs.isEmpty()) {
12871                         mAppOpPermissionPackages.remove(perm);
12872                     }
12873                 }
12874             }
12875         }
12876         if (r != null) {
12877             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12878         }
12879 
12880         N = pkg.instrumentation.size();
12881         r = null;
12882         for (i=0; i<N; i++) {
12883             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12884             mInstrumentation.remove(a.getComponentName());
12885             if (DEBUG_REMOVE && chatty) {
12886                 if (r == null) {
12887                     r = new StringBuilder(256);
12888                 } else {
12889                     r.append(' ');
12890                 }
12891                 r.append(a.info.name);
12892             }
12893         }
12894         if (r != null) {
12895             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12896         }
12897 
12898         r = null;
12899         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12900             // Only system apps can hold shared libraries.
12901             if (pkg.libraryNames != null) {
12902                 for (i = 0; i < pkg.libraryNames.size(); i++) {
12903                     String name = pkg.libraryNames.get(i);
12904                     if (removeSharedLibraryLPw(name, 0)) {
12905                         if (DEBUG_REMOVE && chatty) {
12906                             if (r == null) {
12907                                 r = new StringBuilder(256);
12908                             } else {
12909                                 r.append(' ');
12910                             }
12911                             r.append(name);
12912                         }
12913                     }
12914                 }
12915             }
12916         }
12917 
12918         r = null;
12919 
12920         // Any package can hold static shared libraries.
12921         if (pkg.staticSharedLibName != null) {
12922             if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12923                 if (DEBUG_REMOVE && chatty) {
12924                     if (r == null) {
12925                         r = new StringBuilder(256);
12926                     } else {
12927                         r.append(' ');
12928                     }
12929                     r.append(pkg.staticSharedLibName);
12930                 }
12931             }
12932         }
12933 
12934         if (r != null) {
12935             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12936         }
12937     }
12938 
hasPermission(PackageParser.Package pkgInfo, String perm)12939     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12940         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12941             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12942                 return true;
12943             }
12944         }
12945         return false;
12946     }
12947 
12948     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12949     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12950     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12951 
updatePermissionsLPw(PackageParser.Package pkg, int flags)12952     private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12953         // Update the parent permissions
12954         updatePermissionsLPw(pkg.packageName, pkg, flags);
12955         // Update the child permissions
12956         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12957         for (int i = 0; i < childCount; i++) {
12958             PackageParser.Package childPkg = pkg.childPackages.get(i);
12959             updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12960         }
12961     }
12962 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)12963     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12964             int flags) {
12965         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12966         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12967     }
12968 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags)12969     private void updatePermissionsLPw(String changingPkg,
12970             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12971         // Make sure there are no dangling permission trees.
12972         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12973         while (it.hasNext()) {
12974             final BasePermission bp = it.next();
12975             if (bp.packageSetting == null) {
12976                 // We may not yet have parsed the package, so just see if
12977                 // we still know about its settings.
12978                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12979             }
12980             if (bp.packageSetting == null) {
12981                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12982                         + " from package " + bp.sourcePackage);
12983                 it.remove();
12984             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12985                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12986                     Slog.i(TAG, "Removing old permission tree: " + bp.name
12987                             + " from package " + bp.sourcePackage);
12988                     flags |= UPDATE_PERMISSIONS_ALL;
12989                     it.remove();
12990                 }
12991             }
12992         }
12993 
12994         // Make sure all dynamic permissions have been assigned to a package,
12995         // and make sure there are no dangling permissions.
12996         it = mSettings.mPermissions.values().iterator();
12997         while (it.hasNext()) {
12998             final BasePermission bp = it.next();
12999             if (bp.type == BasePermission.TYPE_DYNAMIC) {
13000                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
13001                         + bp.name + " pkg=" + bp.sourcePackage
13002                         + " info=" + bp.pendingInfo);
13003                 if (bp.packageSetting == null && bp.pendingInfo != null) {
13004                     final BasePermission tree = findPermissionTreeLP(bp.name);
13005                     if (tree != null && tree.perm != null) {
13006                         bp.packageSetting = tree.packageSetting;
13007                         bp.perm = new PackageParser.Permission(tree.perm.owner,
13008                                 new PermissionInfo(bp.pendingInfo));
13009                         bp.perm.info.packageName = tree.perm.info.packageName;
13010                         bp.perm.info.name = bp.name;
13011                         bp.uid = tree.uid;
13012                     }
13013                 }
13014             }
13015             if (bp.packageSetting == null) {
13016                 // We may not yet have parsed the package, so just see if
13017                 // we still know about its settings.
13018                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
13019             }
13020             if (bp.packageSetting == null) {
13021                 Slog.w(TAG, "Removing dangling permission: " + bp.name
13022                         + " from package " + bp.sourcePackage);
13023                 it.remove();
13024             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
13025                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
13026                     Slog.i(TAG, "Removing old permission: " + bp.name
13027                             + " from package " + bp.sourcePackage);
13028                     flags |= UPDATE_PERMISSIONS_ALL;
13029                     it.remove();
13030                 }
13031             }
13032         }
13033 
13034         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
13035         // Now update the permissions for all packages, in particular
13036         // replace the granted permissions of the system packages.
13037         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
13038             for (PackageParser.Package pkg : mPackages.values()) {
13039                 if (pkg != pkgInfo) {
13040                     // Only replace for packages on requested volume
13041                     final String volumeUuid = getVolumeUuidForPackage(pkg);
13042                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
13043                             && Objects.equals(replaceVolumeUuid, volumeUuid);
13044                     grantPermissionsLPw(pkg, replace, changingPkg);
13045                 }
13046             }
13047         }
13048 
13049         if (pkgInfo != null) {
13050             // Only replace for packages on requested volume
13051             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
13052             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
13053                     && Objects.equals(replaceVolumeUuid, volumeUuid);
13054             grantPermissionsLPw(pkgInfo, replace, changingPkg);
13055         }
13056         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13057     }
13058 
grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)13059     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
13060             String packageOfInterest) {
13061         // IMPORTANT: There are two types of permissions: install and runtime.
13062         // Install time permissions are granted when the app is installed to
13063         // all device users and users added in the future. Runtime permissions
13064         // are granted at runtime explicitly to specific users. Normal and signature
13065         // protected permissions are install time permissions. Dangerous permissions
13066         // are install permissions if the app's target SDK is Lollipop MR1 or older,
13067         // otherwise they are runtime permissions. This function does not manage
13068         // runtime permissions except for the case an app targeting Lollipop MR1
13069         // being upgraded to target a newer SDK, in which case dangerous permissions
13070         // are transformed from install time to runtime ones.
13071 
13072         final PackageSetting ps = (PackageSetting) pkg.mExtras;
13073         if (ps == null) {
13074             return;
13075         }
13076 
13077         PermissionsState permissionsState = ps.getPermissionsState();
13078         PermissionsState origPermissions = permissionsState;
13079 
13080         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
13081 
13082         boolean runtimePermissionsRevoked = false;
13083         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
13084 
13085         boolean changedInstallPermission = false;
13086 
13087         if (replace) {
13088             ps.installPermissionsFixed = false;
13089             if (!ps.isSharedUser()) {
13090                 origPermissions = new PermissionsState(permissionsState);
13091                 permissionsState.reset();
13092             } else {
13093                 // We need to know only about runtime permission changes since the
13094                 // calling code always writes the install permissions state but
13095                 // the runtime ones are written only if changed. The only cases of
13096                 // changed runtime permissions here are promotion of an install to
13097                 // runtime and revocation of a runtime from a shared user.
13098                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
13099                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
13100                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
13101                     runtimePermissionsRevoked = true;
13102                 }
13103             }
13104         }
13105 
13106         permissionsState.setGlobalGids(mGlobalGids);
13107 
13108         final int N = pkg.requestedPermissions.size();
13109         for (int i=0; i<N; i++) {
13110             final String name = pkg.requestedPermissions.get(i);
13111             final BasePermission bp = mSettings.mPermissions.get(name);
13112             final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
13113                     >= Build.VERSION_CODES.M;
13114 
13115             if (DEBUG_INSTALL) {
13116                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
13117             }
13118 
13119             if (bp == null || bp.packageSetting == null) {
13120                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
13121                     if (DEBUG_PERMISSIONS) {
13122                         Slog.i(TAG, "Unknown permission " + name
13123                                 + " in package " + pkg.packageName);
13124                     }
13125                 }
13126                 continue;
13127             }
13128 
13129 
13130             // Limit ephemeral apps to ephemeral allowed permissions.
13131             if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
13132                 if (DEBUG_PERMISSIONS) {
13133                     Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
13134                             + pkg.packageName);
13135                 }
13136                 continue;
13137             }
13138 
13139             if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
13140                 if (DEBUG_PERMISSIONS) {
13141                     Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
13142                             + pkg.packageName);
13143                 }
13144                 continue;
13145             }
13146 
13147             final String perm = bp.name;
13148             boolean allowedSig = false;
13149             int grant = GRANT_DENIED;
13150 
13151             // Keep track of app op permissions.
13152             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
13153                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
13154                 if (pkgs == null) {
13155                     pkgs = new ArraySet<>();
13156                     mAppOpPermissionPackages.put(bp.name, pkgs);
13157                 }
13158                 pkgs.add(pkg.packageName);
13159             }
13160 
13161             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
13162             switch (level) {
13163                 case PermissionInfo.PROTECTION_NORMAL: {
13164                     // For all apps normal permissions are install time ones.
13165                     grant = GRANT_INSTALL;
13166                 } break;
13167 
13168                 case PermissionInfo.PROTECTION_DANGEROUS: {
13169                     // If a permission review is required for legacy apps we represent
13170                     // their permissions as always granted runtime ones since we need
13171                     // to keep the review required permission flag per user while an
13172                     // install permission's state is shared across all users.
13173                     if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
13174                         // For legacy apps dangerous permissions are install time ones.
13175                         grant = GRANT_INSTALL;
13176                     } else if (origPermissions.hasInstallPermission(bp.name)) {
13177                         // For legacy apps that became modern, install becomes runtime.
13178                         grant = GRANT_UPGRADE;
13179                     } else if (mPromoteSystemApps
13180                             && isSystemApp(ps)
13181                             && mExistingSystemPackages.contains(ps.name)) {
13182                         // For legacy system apps, install becomes runtime.
13183                         // We cannot check hasInstallPermission() for system apps since those
13184                         // permissions were granted implicitly and not persisted pre-M.
13185                         grant = GRANT_UPGRADE;
13186                     } else {
13187                         // For modern apps keep runtime permissions unchanged.
13188                         grant = GRANT_RUNTIME;
13189                     }
13190                 } break;
13191 
13192                 case PermissionInfo.PROTECTION_SIGNATURE: {
13193                     // For all apps signature permissions are install time ones.
13194                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
13195                     if (allowedSig) {
13196                         grant = GRANT_INSTALL;
13197                     }
13198                 } break;
13199             }
13200 
13201             if (DEBUG_PERMISSIONS) {
13202                 Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
13203             }
13204 
13205             if (grant != GRANT_DENIED) {
13206                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
13207                     // If this is an existing, non-system package, then
13208                     // we can't add any new permissions to it.
13209                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
13210                         // Except...  if this is a permission that was added
13211                         // to the platform (note: need to only do this when
13212                         // updating the platform).
13213                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
13214                             grant = GRANT_DENIED;
13215                         }
13216                     }
13217                 }
13218 
13219                 switch (grant) {
13220                     case GRANT_INSTALL: {
13221                         // Revoke this as runtime permission to handle the case of
13222                         // a runtime permission being downgraded to an install one.
13223                         // Also in permission review mode we keep dangerous permissions
13224                         // for legacy apps
13225                         for (int userId : UserManagerService.getInstance().getUserIds()) {
13226                             if (origPermissions.getRuntimePermissionState(
13227                                     bp.name, userId) != null) {
13228                                 // Revoke the runtime permission and clear the flags.
13229                                 origPermissions.revokeRuntimePermission(bp, userId);
13230                                 origPermissions.updatePermissionFlags(bp, userId,
13231                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
13232                                 // If we revoked a permission permission, we have to write.
13233                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13234                                         changedRuntimePermissionUserIds, userId);
13235                             }
13236                         }
13237                         // Grant an install permission.
13238                         if (permissionsState.grantInstallPermission(bp) !=
13239                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
13240                             changedInstallPermission = true;
13241                         }
13242                     } break;
13243 
13244                     case GRANT_RUNTIME: {
13245                         // Grant previously granted runtime permissions.
13246                         for (int userId : UserManagerService.getInstance().getUserIds()) {
13247                             PermissionState permissionState = origPermissions
13248                                     .getRuntimePermissionState(bp.name, userId);
13249                             int flags = permissionState != null
13250                                     ? permissionState.getFlags() : 0;
13251                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
13252                                 // Don't propagate the permission in a permission review mode if
13253                                 // the former was revoked, i.e. marked to not propagate on upgrade.
13254                                 // Note that in a permission review mode install permissions are
13255                                 // represented as constantly granted runtime ones since we need to
13256                                 // keep a per user state associated with the permission. Also the
13257                                 // revoke on upgrade flag is no longer applicable and is reset.
13258                                 final boolean revokeOnUpgrade = (flags & PackageManager
13259                                         .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
13260                                 if (revokeOnUpgrade) {
13261                                     flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
13262                                     // Since we changed the flags, we have to write.
13263                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13264                                             changedRuntimePermissionUserIds, userId);
13265                                 }
13266                                 if (!mPermissionReviewRequired || !revokeOnUpgrade) {
13267                                     if (permissionsState.grantRuntimePermission(bp, userId) ==
13268                                             PermissionsState.PERMISSION_OPERATION_FAILURE) {
13269                                         // If we cannot put the permission as it was,
13270                                         // we have to write.
13271                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13272                                                 changedRuntimePermissionUserIds, userId);
13273                                     }
13274                                 }
13275 
13276                                 // If the app supports runtime permissions no need for a review.
13277                                 if (mPermissionReviewRequired
13278                                         && appSupportsRuntimePermissions
13279                                         && (flags & PackageManager
13280                                                 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
13281                                     flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
13282                                     // Since we changed the flags, we have to write.
13283                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13284                                             changedRuntimePermissionUserIds, userId);
13285                                 }
13286                             } else if (mPermissionReviewRequired
13287                                     && !appSupportsRuntimePermissions) {
13288                                 // For legacy apps that need a permission review, every new
13289                                 // runtime permission is granted but it is pending a review.
13290                                 // We also need to review only platform defined runtime
13291                                 // permissions as these are the only ones the platform knows
13292                                 // how to disable the API to simulate revocation as legacy
13293                                 // apps don't expect to run with revoked permissions.
13294                                 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
13295                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
13296                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
13297                                         // We changed the flags, hence have to write.
13298                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13299                                                 changedRuntimePermissionUserIds, userId);
13300                                     }
13301                                 }
13302                                 if (permissionsState.grantRuntimePermission(bp, userId)
13303                                         != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13304                                     // We changed the permission, hence have to write.
13305                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13306                                             changedRuntimePermissionUserIds, userId);
13307                                 }
13308                             }
13309                             // Propagate the permission flags.
13310                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
13311                         }
13312                     } break;
13313 
13314                     case GRANT_UPGRADE: {
13315                         // Grant runtime permissions for a previously held install permission.
13316                         PermissionState permissionState = origPermissions
13317                                 .getInstallPermissionState(bp.name);
13318                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
13319 
13320                         if (origPermissions.revokeInstallPermission(bp)
13321                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13322                             // We will be transferring the permission flags, so clear them.
13323                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
13324                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
13325                             changedInstallPermission = true;
13326                         }
13327 
13328                         // If the permission is not to be promoted to runtime we ignore it and
13329                         // also its other flags as they are not applicable to install permissions.
13330                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
13331                             for (int userId : currentUserIds) {
13332                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
13333                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
13334                                     // Transfer the permission flags.
13335                                     permissionsState.updatePermissionFlags(bp, userId,
13336                                             flags, flags);
13337                                     // If we granted the permission, we have to write.
13338                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13339                                             changedRuntimePermissionUserIds, userId);
13340                                 }
13341                             }
13342                         }
13343                     } break;
13344 
13345                     default: {
13346                         if (packageOfInterest == null
13347                                 || packageOfInterest.equals(pkg.packageName)) {
13348                             if (DEBUG_PERMISSIONS) {
13349                                 Slog.i(TAG, "Not granting permission " + perm
13350                                         + " to package " + pkg.packageName
13351                                         + " because it was previously installed without");
13352                             }
13353                         }
13354                     } break;
13355                 }
13356             } else {
13357                 if (permissionsState.revokeInstallPermission(bp) !=
13358                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
13359                     // Also drop the permission flags.
13360                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
13361                             PackageManager.MASK_PERMISSION_FLAGS, 0);
13362                     changedInstallPermission = true;
13363                     Slog.i(TAG, "Un-granting permission " + perm
13364                             + " from package " + pkg.packageName
13365                             + " (protectionLevel=" + bp.protectionLevel
13366                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13367                             + ")");
13368                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
13369                     // Don't print warning for app op permissions, since it is fine for them
13370                     // not to be granted, there is a UI for the user to decide.
13371                     if (DEBUG_PERMISSIONS
13372                             && (packageOfInterest == null
13373                                     || packageOfInterest.equals(pkg.packageName))) {
13374                         Slog.i(TAG, "Not granting permission " + perm
13375                                 + " to package " + pkg.packageName
13376                                 + " (protectionLevel=" + bp.protectionLevel
13377                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13378                                 + ")");
13379                     }
13380                 }
13381             }
13382         }
13383 
13384         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
13385                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
13386             // This is the first that we have heard about this package, so the
13387             // permissions we have now selected are fixed until explicitly
13388             // changed.
13389             ps.installPermissionsFixed = true;
13390         }
13391 
13392         // Persist the runtime permissions state for users with changes. If permissions
13393         // were revoked because no app in the shared user declares them we have to
13394         // write synchronously to avoid losing runtime permissions state.
13395         for (int userId : changedRuntimePermissionUserIds) {
13396             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
13397         }
13398     }
13399 
isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)13400     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
13401         boolean allowed = false;
13402         final int NP = PackageParser.NEW_PERMISSIONS.length;
13403         for (int ip=0; ip<NP; ip++) {
13404             final PackageParser.NewPermissionInfo npi
13405                     = PackageParser.NEW_PERMISSIONS[ip];
13406             if (npi.name.equals(perm)
13407                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
13408                 allowed = true;
13409                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
13410                         + pkg.packageName);
13411                 break;
13412             }
13413         }
13414         return allowed;
13415     }
13416 
grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions)13417     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
13418             BasePermission bp, PermissionsState origPermissions) {
13419         boolean privilegedPermission = (bp.protectionLevel
13420                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
13421         boolean privappPermissionsDisable =
13422                 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
13423         boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
13424         boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
13425         if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
13426                 && !platformPackage && platformPermission) {
13427             final ArraySet<String> allowedPermissions = SystemConfig.getInstance()
13428                     .getPrivAppPermissions(pkg.packageName);
13429             final boolean whitelisted =
13430                     allowedPermissions != null && allowedPermissions.contains(perm);
13431             if (!whitelisted) {
13432                 Slog.w(TAG, "Privileged permission " + perm + " for package "
13433                         + pkg.packageName + " - not in privapp-permissions whitelist");
13434                 // Only report violations for apps on system image
13435                 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
13436                     // it's only a reportable violation if the permission isn't explicitly denied
13437                     final ArraySet<String> deniedPermissions = SystemConfig.getInstance()
13438                             .getPrivAppDenyPermissions(pkg.packageName);
13439                     final boolean permissionViolation =
13440                             deniedPermissions == null || !deniedPermissions.contains(perm);
13441                     if (permissionViolation) {
13442                         if (mPrivappPermissionsViolations == null) {
13443                             mPrivappPermissionsViolations = new ArraySet<>();
13444                         }
13445                         mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
13446                     } else {
13447                         return false;
13448                     }
13449                 }
13450                 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
13451                     return false;
13452                 }
13453             }
13454         }
13455         boolean allowed = (compareSignatures(
13456                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
13457                         == PackageManager.SIGNATURE_MATCH)
13458                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
13459                         == PackageManager.SIGNATURE_MATCH);
13460         if (!allowed && privilegedPermission) {
13461             if (isSystemApp(pkg)) {
13462                 // For updated system applications, a system permission
13463                 // is granted only if it had been defined by the original application.
13464                 if (pkg.isUpdatedSystemApp()) {
13465                     final PackageSetting sysPs = mSettings
13466                             .getDisabledSystemPkgLPr(pkg.packageName);
13467                     if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
13468                         // If the original was granted this permission, we take
13469                         // that grant decision as read and propagate it to the
13470                         // update.
13471                         if (sysPs.isPrivileged()) {
13472                             allowed = true;
13473                         }
13474                     } else {
13475                         // The system apk may have been updated with an older
13476                         // version of the one on the data partition, but which
13477                         // granted a new system permission that it didn't have
13478                         // before.  In this case we do want to allow the app to
13479                         // now get the new permission if the ancestral apk is
13480                         // privileged to get it.
13481                         if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
13482                             for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
13483                                 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
13484                                     allowed = true;
13485                                     break;
13486                                 }
13487                             }
13488                         }
13489                         // Also if a privileged parent package on the system image or any of
13490                         // its children requested a privileged permission, the updated child
13491                         // packages can also get the permission.
13492                         if (pkg.parentPackage != null) {
13493                             final PackageSetting disabledSysParentPs = mSettings
13494                                     .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
13495                             if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
13496                                     && disabledSysParentPs.isPrivileged()) {
13497                                 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
13498                                     allowed = true;
13499                                 } else if (disabledSysParentPs.pkg.childPackages != null) {
13500                                     final int count = disabledSysParentPs.pkg.childPackages.size();
13501                                     for (int i = 0; i < count; i++) {
13502                                         PackageParser.Package disabledSysChildPkg =
13503                                                 disabledSysParentPs.pkg.childPackages.get(i);
13504                                         if (isPackageRequestingPermission(disabledSysChildPkg,
13505                                                 perm)) {
13506                                             allowed = true;
13507                                             break;
13508                                         }
13509                                     }
13510                                 }
13511                             }
13512                         }
13513                     }
13514                 } else {
13515                     allowed = isPrivilegedApp(pkg);
13516                 }
13517             }
13518         }
13519         if (!allowed) {
13520             if (!allowed && (bp.protectionLevel
13521                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
13522                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
13523                 // If this was a previously normal/dangerous permission that got moved
13524                 // to a system permission as part of the runtime permission redesign, then
13525                 // we still want to blindly grant it to old apps.
13526                 allowed = true;
13527             }
13528             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
13529                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
13530                 // If this permission is to be granted to the system installer and
13531                 // this app is an installer, then it gets the permission.
13532                 allowed = true;
13533             }
13534             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
13535                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
13536                 // If this permission is to be granted to the system verifier and
13537                 // this app is a verifier, then it gets the permission.
13538                 allowed = true;
13539             }
13540             if (!allowed && (bp.protectionLevel
13541                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
13542                     && isSystemApp(pkg)) {
13543                 // Any pre-installed system app is allowed to get this permission.
13544                 allowed = true;
13545             }
13546             if (!allowed && (bp.protectionLevel
13547                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
13548                 // For development permissions, a development permission
13549                 // is granted only if it was already granted.
13550                 allowed = origPermissions.hasInstallPermission(perm);
13551             }
13552             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
13553                     && pkg.packageName.equals(mSetupWizardPackage)) {
13554                 // If this permission is to be granted to the system setup wizard and
13555                 // this app is a setup wizard, then it gets the permission.
13556                 allowed = true;
13557             }
13558         }
13559         return allowed;
13560     }
13561 
isPackageRequestingPermission(PackageParser.Package pkg, String permission)13562     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
13563         final int permCount = pkg.requestedPermissions.size();
13564         for (int j = 0; j < permCount; j++) {
13565             String requestedPermission = pkg.requestedPermissions.get(j);
13566             if (permission.equals(requestedPermission)) {
13567                 return true;
13568             }
13569         }
13570         return false;
13571     }
13572 
13573     final class ActivityIntentResolver
13574             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)13575         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13576                 boolean defaultOnly, int userId) {
13577             if (!sUserManager.exists(userId)) return null;
13578             mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
13579             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13580         }
13581 
queryIntent(Intent intent, String resolvedType, int flags, int userId)13582         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13583                 int userId) {
13584             if (!sUserManager.exists(userId)) return null;
13585             mFlags = flags;
13586             return super.queryIntent(intent, resolvedType,
13587                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13588                     userId);
13589         }
13590 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)13591         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13592                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
13593             if (!sUserManager.exists(userId)) return null;
13594             if (packageActivities == null) {
13595                 return null;
13596             }
13597             mFlags = flags;
13598             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13599             final int N = packageActivities.size();
13600             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
13601                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
13602 
13603             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
13604             for (int i = 0; i < N; ++i) {
13605                 intentFilters = packageActivities.get(i).intents;
13606                 if (intentFilters != null && intentFilters.size() > 0) {
13607                     PackageParser.ActivityIntentInfo[] array =
13608                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
13609                     intentFilters.toArray(array);
13610                     listCut.add(array);
13611                 }
13612             }
13613             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13614         }
13615 
13616         /**
13617          * Finds a privileged activity that matches the specified activity names.
13618          */
findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo)13619         private PackageParser.Activity findMatchingActivity(
13620                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
13621             for (PackageParser.Activity sysActivity : activityList) {
13622                 if (sysActivity.info.name.equals(activityInfo.name)) {
13623                     return sysActivity;
13624                 }
13625                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
13626                     return sysActivity;
13627                 }
13628                 if (sysActivity.info.targetActivity != null) {
13629                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
13630                         return sysActivity;
13631                     }
13632                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
13633                         return sysActivity;
13634                     }
13635                 }
13636             }
13637             return null;
13638         }
13639 
13640         public class IterGenerator<E> {
generate(ActivityIntentInfo info)13641             public Iterator<E> generate(ActivityIntentInfo info) {
13642                 return null;
13643             }
13644         }
13645 
13646         public class ActionIterGenerator extends IterGenerator<String> {
13647             @Override
generate(ActivityIntentInfo info)13648             public Iterator<String> generate(ActivityIntentInfo info) {
13649                 return info.actionsIterator();
13650             }
13651         }
13652 
13653         public class CategoriesIterGenerator extends IterGenerator<String> {
13654             @Override
generate(ActivityIntentInfo info)13655             public Iterator<String> generate(ActivityIntentInfo info) {
13656                 return info.categoriesIterator();
13657             }
13658         }
13659 
13660         public class SchemesIterGenerator extends IterGenerator<String> {
13661             @Override
generate(ActivityIntentInfo info)13662             public Iterator<String> generate(ActivityIntentInfo info) {
13663                 return info.schemesIterator();
13664             }
13665         }
13666 
13667         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
13668             @Override
generate(ActivityIntentInfo info)13669             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
13670                 return info.authoritiesIterator();
13671             }
13672         }
13673 
13674         /**
13675          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
13676          * MODIFIED. Do not pass in a list that should not be changed.
13677          */
getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator)13678         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
13679                 IterGenerator<T> generator, Iterator<T> searchIterator) {
13680             // loop through the set of actions; every one must be found in the intent filter
13681             while (searchIterator.hasNext()) {
13682                 // we must have at least one filter in the list to consider a match
13683                 if (intentList.size() == 0) {
13684                     break;
13685                 }
13686 
13687                 final T searchAction = searchIterator.next();
13688 
13689                 // loop through the set of intent filters
13690                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
13691                 while (intentIter.hasNext()) {
13692                     final ActivityIntentInfo intentInfo = intentIter.next();
13693                     boolean selectionFound = false;
13694 
13695                     // loop through the intent filter's selection criteria; at least one
13696                     // of them must match the searched criteria
13697                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
13698                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
13699                         final T intentSelection = intentSelectionIter.next();
13700                         if (intentSelection != null && intentSelection.equals(searchAction)) {
13701                             selectionFound = true;
13702                             break;
13703                         }
13704                     }
13705 
13706                     // the selection criteria wasn't found in this filter's set; this filter
13707                     // is not a potential match
13708                     if (!selectionFound) {
13709                         intentIter.remove();
13710                     }
13711                 }
13712             }
13713         }
13714 
isProtectedAction(ActivityIntentInfo filter)13715         private boolean isProtectedAction(ActivityIntentInfo filter) {
13716             final Iterator<String> actionsIter = filter.actionsIterator();
13717             while (actionsIter != null && actionsIter.hasNext()) {
13718                 final String filterAction = actionsIter.next();
13719                 if (PROTECTED_ACTIONS.contains(filterAction)) {
13720                     return true;
13721                 }
13722             }
13723             return false;
13724         }
13725 
13726         /**
13727          * Adjusts the priority of the given intent filter according to policy.
13728          * <p>
13729          * <ul>
13730          * <li>The priority for non privileged applications is capped to '0'</li>
13731          * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13732          * <li>The priority for unbundled updates to privileged applications is capped to the
13733          *      priority defined on the system partition</li>
13734          * </ul>
13735          * <p>
13736          * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13737          * allowed to obtain any priority on any action.
13738          */
adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent)13739         private void adjustPriority(
13740                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13741             // nothing to do; priority is fine as-is
13742             if (intent.getPriority() <= 0) {
13743                 return;
13744             }
13745 
13746             final ActivityInfo activityInfo = intent.activity.info;
13747             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13748 
13749             final boolean privilegedApp =
13750                     ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13751             if (!privilegedApp) {
13752                 // non-privileged applications can never define a priority >0
13753                 if (DEBUG_FILTERS) {
13754                     Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13755                             + " package: " + applicationInfo.packageName
13756                             + " activity: " + intent.activity.className
13757                             + " origPrio: " + intent.getPriority());
13758                 }
13759                 intent.setPriority(0);
13760                 return;
13761             }
13762 
13763             if (systemActivities == null) {
13764                 // the system package is not disabled; we're parsing the system partition
13765                 if (isProtectedAction(intent)) {
13766                     if (mDeferProtectedFilters) {
13767                         // We can't deal with these just yet. No component should ever obtain a
13768                         // >0 priority for a protected actions, with ONE exception -- the setup
13769                         // wizard. The setup wizard, however, cannot be known until we're able to
13770                         // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13771                         // until all intent filters have been processed. Chicken, meet egg.
13772                         // Let the filter temporarily have a high priority and rectify the
13773                         // priorities after all system packages have been scanned.
13774                         mProtectedFilters.add(intent);
13775                         if (DEBUG_FILTERS) {
13776                             Slog.i(TAG, "Protected action; save for later;"
13777                                     + " package: " + applicationInfo.packageName
13778                                     + " activity: " + intent.activity.className
13779                                     + " origPrio: " + intent.getPriority());
13780                         }
13781                         return;
13782                     } else {
13783                         if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13784                             Slog.i(TAG, "No setup wizard;"
13785                                 + " All protected intents capped to priority 0");
13786                         }
13787                         if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13788                             if (DEBUG_FILTERS) {
13789                                 Slog.i(TAG, "Found setup wizard;"
13790                                     + " allow priority " + intent.getPriority() + ";"
13791                                     + " package: " + intent.activity.info.packageName
13792                                     + " activity: " + intent.activity.className
13793                                     + " priority: " + intent.getPriority());
13794                             }
13795                             // setup wizard gets whatever it wants
13796                             return;
13797                         }
13798                         if (DEBUG_FILTERS) {
13799                             Slog.i(TAG, "Protected action; cap priority to 0;"
13800                                     + " package: " + intent.activity.info.packageName
13801                                     + " activity: " + intent.activity.className
13802                                     + " origPrio: " + intent.getPriority());
13803                         }
13804                         intent.setPriority(0);
13805                         return;
13806                     }
13807                 }
13808                 // privileged apps on the system image get whatever priority they request
13809                 return;
13810             }
13811 
13812             // privileged app unbundled update ... try to find the same activity
13813             final PackageParser.Activity foundActivity =
13814                     findMatchingActivity(systemActivities, activityInfo);
13815             if (foundActivity == null) {
13816                 // this is a new activity; it cannot obtain >0 priority
13817                 if (DEBUG_FILTERS) {
13818                     Slog.i(TAG, "New activity; cap priority to 0;"
13819                             + " package: " + applicationInfo.packageName
13820                             + " activity: " + intent.activity.className
13821                             + " origPrio: " + intent.getPriority());
13822                 }
13823                 intent.setPriority(0);
13824                 return;
13825             }
13826 
13827             // found activity, now check for filter equivalence
13828 
13829             // a shallow copy is enough; we modify the list, not its contents
13830             final List<ActivityIntentInfo> intentListCopy =
13831                     new ArrayList<>(foundActivity.intents);
13832             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13833 
13834             // find matching action subsets
13835             final Iterator<String> actionsIterator = intent.actionsIterator();
13836             if (actionsIterator != null) {
13837                 getIntentListSubset(
13838                         intentListCopy, new ActionIterGenerator(), actionsIterator);
13839                 if (intentListCopy.size() == 0) {
13840                     // no more intents to match; we're not equivalent
13841                     if (DEBUG_FILTERS) {
13842                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
13843                                 + " package: " + applicationInfo.packageName
13844                                 + " activity: " + intent.activity.className
13845                                 + " origPrio: " + intent.getPriority());
13846                     }
13847                     intent.setPriority(0);
13848                     return;
13849                 }
13850             }
13851 
13852             // find matching category subsets
13853             final Iterator<String> categoriesIterator = intent.categoriesIterator();
13854             if (categoriesIterator != null) {
13855                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13856                         categoriesIterator);
13857                 if (intentListCopy.size() == 0) {
13858                     // no more intents to match; we're not equivalent
13859                     if (DEBUG_FILTERS) {
13860                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
13861                                 + " package: " + applicationInfo.packageName
13862                                 + " activity: " + intent.activity.className
13863                                 + " origPrio: " + intent.getPriority());
13864                     }
13865                     intent.setPriority(0);
13866                     return;
13867                 }
13868             }
13869 
13870             // find matching schemes subsets
13871             final Iterator<String> schemesIterator = intent.schemesIterator();
13872             if (schemesIterator != null) {
13873                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13874                         schemesIterator);
13875                 if (intentListCopy.size() == 0) {
13876                     // no more intents to match; we're not equivalent
13877                     if (DEBUG_FILTERS) {
13878                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13879                                 + " package: " + applicationInfo.packageName
13880                                 + " activity: " + intent.activity.className
13881                                 + " origPrio: " + intent.getPriority());
13882                     }
13883                     intent.setPriority(0);
13884                     return;
13885                 }
13886             }
13887 
13888             // find matching authorities subsets
13889             final Iterator<IntentFilter.AuthorityEntry>
13890                     authoritiesIterator = intent.authoritiesIterator();
13891             if (authoritiesIterator != null) {
13892                 getIntentListSubset(intentListCopy,
13893                         new AuthoritiesIterGenerator(),
13894                         authoritiesIterator);
13895                 if (intentListCopy.size() == 0) {
13896                     // no more intents to match; we're not equivalent
13897                     if (DEBUG_FILTERS) {
13898                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13899                                 + " package: " + applicationInfo.packageName
13900                                 + " activity: " + intent.activity.className
13901                                 + " origPrio: " + intent.getPriority());
13902                     }
13903                     intent.setPriority(0);
13904                     return;
13905                 }
13906             }
13907 
13908             // we found matching filter(s); app gets the max priority of all intents
13909             int cappedPriority = 0;
13910             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13911                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13912             }
13913             if (intent.getPriority() > cappedPriority) {
13914                 if (DEBUG_FILTERS) {
13915                     Slog.i(TAG, "Found matching filter(s);"
13916                             + " cap priority to " + cappedPriority + ";"
13917                             + " package: " + applicationInfo.packageName
13918                             + " activity: " + intent.activity.className
13919                             + " origPrio: " + intent.getPriority());
13920                 }
13921                 intent.setPriority(cappedPriority);
13922                 return;
13923             }
13924             // all this for nothing; the requested priority was <= what was on the system
13925         }
13926 
addActivity(PackageParser.Activity a, String type)13927         public final void addActivity(PackageParser.Activity a, String type) {
13928             mActivities.put(a.getComponentName(), a);
13929             if (DEBUG_SHOW_INFO)
13930                 Log.v(
13931                 TAG, "  " + type + " " +
13932                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13933             if (DEBUG_SHOW_INFO)
13934                 Log.v(TAG, "    Class=" + a.info.name);
13935             final int NI = a.intents.size();
13936             for (int j=0; j<NI; j++) {
13937                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13938                 if ("activity".equals(type)) {
13939                     final PackageSetting ps =
13940                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13941                     final List<PackageParser.Activity> systemActivities =
13942                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
13943                     adjustPriority(systemActivities, intent);
13944                 }
13945                 if (DEBUG_SHOW_INFO) {
13946                     Log.v(TAG, "    IntentFilter:");
13947                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13948                 }
13949                 if (!intent.debugCheck()) {
13950                     Log.w(TAG, "==> For Activity " + a.info.name);
13951                 }
13952                 addFilter(intent);
13953             }
13954         }
13955 
removeActivity(PackageParser.Activity a, String type)13956         public final void removeActivity(PackageParser.Activity a, String type) {
13957             mActivities.remove(a.getComponentName());
13958             if (DEBUG_SHOW_INFO) {
13959                 Log.v(TAG, "  " + type + " "
13960                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13961                                 : a.info.name) + ":");
13962                 Log.v(TAG, "    Class=" + a.info.name);
13963             }
13964             final int NI = a.intents.size();
13965             for (int j=0; j<NI; j++) {
13966                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13967                 if (DEBUG_SHOW_INFO) {
13968                     Log.v(TAG, "    IntentFilter:");
13969                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13970                 }
13971                 removeFilter(intent);
13972             }
13973         }
13974 
13975         @Override
allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)13976         protected boolean allowFilterResult(
13977                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13978             ActivityInfo filterAi = filter.activity.info;
13979             for (int i=dest.size()-1; i>=0; i--) {
13980                 ActivityInfo destAi = dest.get(i).activityInfo;
13981                 if (destAi.name == filterAi.name
13982                         && destAi.packageName == filterAi.packageName) {
13983                     return false;
13984                 }
13985             }
13986             return true;
13987         }
13988 
13989         @Override
newArray(int size)13990         protected ActivityIntentInfo[] newArray(int size) {
13991             return new ActivityIntentInfo[size];
13992         }
13993 
13994         @Override
isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)13995         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13996             if (!sUserManager.exists(userId)) return true;
13997             PackageParser.Package p = filter.activity.owner;
13998             if (p != null) {
13999                 PackageSetting ps = (PackageSetting)p.mExtras;
14000                 if (ps != null) {
14001                     // System apps are never considered stopped for purposes of
14002                     // filtering, because there may be no way for the user to
14003                     // actually re-launch them.
14004                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
14005                             && ps.getStopped(userId);
14006                 }
14007             }
14008             return false;
14009         }
14010 
14011         @Override
isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)14012         protected boolean isPackageForFilter(String packageName,
14013                 PackageParser.ActivityIntentInfo info) {
14014             return packageName.equals(info.activity.owner.packageName);
14015         }
14016 
14017         @Override
newResult(PackageParser.ActivityIntentInfo info, int match, int userId)14018         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
14019                 int match, int userId) {
14020             if (!sUserManager.exists(userId)) return null;
14021             if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
14022                 return null;
14023             }
14024             final PackageParser.Activity activity = info.activity;
14025             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
14026             if (ps == null) {
14027                 return null;
14028             }
14029             final PackageUserState userState = ps.readUserState(userId);
14030             ActivityInfo ai =
14031                     PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
14032             if (ai == null) {
14033                 return null;
14034             }
14035             final boolean matchExplicitlyVisibleOnly =
14036                     (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
14037             final boolean matchVisibleToInstantApp =
14038                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14039             final boolean componentVisible =
14040                     matchVisibleToInstantApp
14041                     && info.isVisibleToInstantApp()
14042                     && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
14043             final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14044             // throw out filters that aren't visible to ephemeral apps
14045             if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
14046                 return null;
14047             }
14048             // throw out instant app filters if we're not explicitly requesting them
14049             if (!matchInstantApp && userState.instantApp) {
14050                 return null;
14051             }
14052             // throw out instant app filters if updates are available; will trigger
14053             // instant app resolution
14054             if (userState.instantApp && ps.isUpdateAvailable()) {
14055                 return null;
14056             }
14057             final ResolveInfo res = new ResolveInfo();
14058             res.activityInfo = ai;
14059             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
14060                 res.filter = info;
14061             }
14062             if (info != null) {
14063                 res.handleAllWebDataURI = info.handleAllWebDataURI();
14064             }
14065             res.priority = info.getPriority();
14066             res.preferredOrder = activity.owner.mPreferredOrder;
14067             //System.out.println("Result: " + res.activityInfo.className +
14068             //                   " = " + res.priority);
14069             res.match = match;
14070             res.isDefault = info.hasDefault;
14071             res.labelRes = info.labelRes;
14072             res.nonLocalizedLabel = info.nonLocalizedLabel;
14073             if (userNeedsBadging(userId)) {
14074                 res.noResourceId = true;
14075             } else {
14076                 res.icon = info.icon;
14077             }
14078             res.iconResourceId = info.icon;
14079             res.system = res.activityInfo.applicationInfo.isSystemApp();
14080             res.isInstantAppAvailable = userState.instantApp;
14081             return res;
14082         }
14083 
14084         @Override
sortResults(List<ResolveInfo> results)14085         protected void sortResults(List<ResolveInfo> results) {
14086             Collections.sort(results, mResolvePrioritySorter);
14087         }
14088 
14089         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)14090         protected void dumpFilter(PrintWriter out, String prefix,
14091                 PackageParser.ActivityIntentInfo filter) {
14092             out.print(prefix); out.print(
14093                     Integer.toHexString(System.identityHashCode(filter.activity)));
14094                     out.print(' ');
14095                     filter.activity.printComponentShortName(out);
14096                     out.print(" filter ");
14097                     out.println(Integer.toHexString(System.identityHashCode(filter)));
14098         }
14099 
14100         @Override
filterToLabel(PackageParser.ActivityIntentInfo filter)14101         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
14102             return filter.activity;
14103         }
14104 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)14105         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14106             PackageParser.Activity activity = (PackageParser.Activity)label;
14107             out.print(prefix); out.print(
14108                     Integer.toHexString(System.identityHashCode(activity)));
14109                     out.print(' ');
14110                     activity.printComponentShortName(out);
14111             if (count > 1) {
14112                 out.print(" ("); out.print(count); out.print(" filters)");
14113             }
14114             out.println();
14115         }
14116 
14117         // Keys are String (activity class name), values are Activity.
14118         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
14119                 = new ArrayMap<ComponentName, PackageParser.Activity>();
14120         private int mFlags;
14121     }
14122 
14123     private final class ServiceIntentResolver
14124             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)14125         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14126                 boolean defaultOnly, int userId) {
14127             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14128             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14129         }
14130 
queryIntent(Intent intent, String resolvedType, int flags, int userId)14131         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14132                 int userId) {
14133             if (!sUserManager.exists(userId)) return null;
14134             mFlags = flags;
14135             return super.queryIntent(intent, resolvedType,
14136                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14137                     userId);
14138         }
14139 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)14140         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14141                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
14142             if (!sUserManager.exists(userId)) return null;
14143             if (packageServices == null) {
14144                 return null;
14145             }
14146             mFlags = flags;
14147             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
14148             final int N = packageServices.size();
14149             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
14150                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
14151 
14152             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
14153             for (int i = 0; i < N; ++i) {
14154                 intentFilters = packageServices.get(i).intents;
14155                 if (intentFilters != null && intentFilters.size() > 0) {
14156                     PackageParser.ServiceIntentInfo[] array =
14157                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
14158                     intentFilters.toArray(array);
14159                     listCut.add(array);
14160                 }
14161             }
14162             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14163         }
14164 
addService(PackageParser.Service s)14165         public final void addService(PackageParser.Service s) {
14166             mServices.put(s.getComponentName(), s);
14167             if (DEBUG_SHOW_INFO) {
14168                 Log.v(TAG, "  "
14169                         + (s.info.nonLocalizedLabel != null
14170                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
14171                 Log.v(TAG, "    Class=" + s.info.name);
14172             }
14173             final int NI = s.intents.size();
14174             int j;
14175             for (j=0; j<NI; j++) {
14176                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
14177                 if (DEBUG_SHOW_INFO) {
14178                     Log.v(TAG, "    IntentFilter:");
14179                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14180                 }
14181                 if (!intent.debugCheck()) {
14182                     Log.w(TAG, "==> For Service " + s.info.name);
14183                 }
14184                 addFilter(intent);
14185             }
14186         }
14187 
removeService(PackageParser.Service s)14188         public final void removeService(PackageParser.Service s) {
14189             mServices.remove(s.getComponentName());
14190             if (DEBUG_SHOW_INFO) {
14191                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
14192                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
14193                 Log.v(TAG, "    Class=" + s.info.name);
14194             }
14195             final int NI = s.intents.size();
14196             int j;
14197             for (j=0; j<NI; j++) {
14198                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
14199                 if (DEBUG_SHOW_INFO) {
14200                     Log.v(TAG, "    IntentFilter:");
14201                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14202                 }
14203                 removeFilter(intent);
14204             }
14205         }
14206 
14207         @Override
allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)14208         protected boolean allowFilterResult(
14209                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
14210             ServiceInfo filterSi = filter.service.info;
14211             for (int i=dest.size()-1; i>=0; i--) {
14212                 ServiceInfo destAi = dest.get(i).serviceInfo;
14213                 if (destAi.name == filterSi.name
14214                         && destAi.packageName == filterSi.packageName) {
14215                     return false;
14216                 }
14217             }
14218             return true;
14219         }
14220 
14221         @Override
newArray(int size)14222         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
14223             return new PackageParser.ServiceIntentInfo[size];
14224         }
14225 
14226         @Override
isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)14227         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
14228             if (!sUserManager.exists(userId)) return true;
14229             PackageParser.Package p = filter.service.owner;
14230             if (p != null) {
14231                 PackageSetting ps = (PackageSetting)p.mExtras;
14232                 if (ps != null) {
14233                     // System apps are never considered stopped for purposes of
14234                     // filtering, because there may be no way for the user to
14235                     // actually re-launch them.
14236                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14237                             && ps.getStopped(userId);
14238                 }
14239             }
14240             return false;
14241         }
14242 
14243         @Override
isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)14244         protected boolean isPackageForFilter(String packageName,
14245                 PackageParser.ServiceIntentInfo info) {
14246             return packageName.equals(info.service.owner.packageName);
14247         }
14248 
14249         @Override
newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)14250         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
14251                 int match, int userId) {
14252             if (!sUserManager.exists(userId)) return null;
14253             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
14254             if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
14255                 return null;
14256             }
14257             final PackageParser.Service service = info.service;
14258             PackageSetting ps = (PackageSetting) service.owner.mExtras;
14259             if (ps == null) {
14260                 return null;
14261             }
14262             final PackageUserState userState = ps.readUserState(userId);
14263             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
14264                     userState, userId);
14265             if (si == null) {
14266                 return null;
14267             }
14268             final boolean matchVisibleToInstantApp =
14269                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14270             final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14271             // throw out filters that aren't visible to ephemeral apps
14272             if (matchVisibleToInstantApp
14273                     && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14274                 return null;
14275             }
14276             // throw out ephemeral filters if we're not explicitly requesting them
14277             if (!isInstantApp && userState.instantApp) {
14278                 return null;
14279             }
14280             // throw out instant app filters if updates are available; will trigger
14281             // instant app resolution
14282             if (userState.instantApp && ps.isUpdateAvailable()) {
14283                 return null;
14284             }
14285             final ResolveInfo res = new ResolveInfo();
14286             res.serviceInfo = si;
14287             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
14288                 res.filter = filter;
14289             }
14290             res.priority = info.getPriority();
14291             res.preferredOrder = service.owner.mPreferredOrder;
14292             res.match = match;
14293             res.isDefault = info.hasDefault;
14294             res.labelRes = info.labelRes;
14295             res.nonLocalizedLabel = info.nonLocalizedLabel;
14296             res.icon = info.icon;
14297             res.system = res.serviceInfo.applicationInfo.isSystemApp();
14298             return res;
14299         }
14300 
14301         @Override
sortResults(List<ResolveInfo> results)14302         protected void sortResults(List<ResolveInfo> results) {
14303             Collections.sort(results, mResolvePrioritySorter);
14304         }
14305 
14306         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)14307         protected void dumpFilter(PrintWriter out, String prefix,
14308                 PackageParser.ServiceIntentInfo filter) {
14309             out.print(prefix); out.print(
14310                     Integer.toHexString(System.identityHashCode(filter.service)));
14311                     out.print(' ');
14312                     filter.service.printComponentShortName(out);
14313                     out.print(" filter ");
14314                     out.println(Integer.toHexString(System.identityHashCode(filter)));
14315         }
14316 
14317         @Override
filterToLabel(PackageParser.ServiceIntentInfo filter)14318         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
14319             return filter.service;
14320         }
14321 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)14322         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14323             PackageParser.Service service = (PackageParser.Service)label;
14324             out.print(prefix); out.print(
14325                     Integer.toHexString(System.identityHashCode(service)));
14326                     out.print(' ');
14327                     service.printComponentShortName(out);
14328             if (count > 1) {
14329                 out.print(" ("); out.print(count); out.print(" filters)");
14330             }
14331             out.println();
14332         }
14333 
14334 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
14335 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
14336 //            final List<ResolveInfo> retList = Lists.newArrayList();
14337 //            while (i.hasNext()) {
14338 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
14339 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
14340 //                    retList.add(resolveInfo);
14341 //                }
14342 //            }
14343 //            return retList;
14344 //        }
14345 
14346         // Keys are String (activity class name), values are Activity.
14347         private final ArrayMap<ComponentName, PackageParser.Service> mServices
14348                 = new ArrayMap<ComponentName, PackageParser.Service>();
14349         private int mFlags;
14350     }
14351 
14352     private final class ProviderIntentResolver
14353             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)14354         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14355                 boolean defaultOnly, int userId) {
14356             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14357             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14358         }
14359 
queryIntent(Intent intent, String resolvedType, int flags, int userId)14360         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14361                 int userId) {
14362             if (!sUserManager.exists(userId))
14363                 return null;
14364             mFlags = flags;
14365             return super.queryIntent(intent, resolvedType,
14366                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14367                     userId);
14368         }
14369 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)14370         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14371                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
14372             if (!sUserManager.exists(userId))
14373                 return null;
14374             if (packageProviders == null) {
14375                 return null;
14376             }
14377             mFlags = flags;
14378             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
14379             final int N = packageProviders.size();
14380             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
14381                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
14382 
14383             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
14384             for (int i = 0; i < N; ++i) {
14385                 intentFilters = packageProviders.get(i).intents;
14386                 if (intentFilters != null && intentFilters.size() > 0) {
14387                     PackageParser.ProviderIntentInfo[] array =
14388                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
14389                     intentFilters.toArray(array);
14390                     listCut.add(array);
14391                 }
14392             }
14393             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14394         }
14395 
addProvider(PackageParser.Provider p)14396         public final void addProvider(PackageParser.Provider p) {
14397             if (mProviders.containsKey(p.getComponentName())) {
14398                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
14399                 return;
14400             }
14401 
14402             mProviders.put(p.getComponentName(), p);
14403             if (DEBUG_SHOW_INFO) {
14404                 Log.v(TAG, "  "
14405                         + (p.info.nonLocalizedLabel != null
14406                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
14407                 Log.v(TAG, "    Class=" + p.info.name);
14408             }
14409             final int NI = p.intents.size();
14410             int j;
14411             for (j = 0; j < NI; j++) {
14412                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14413                 if (DEBUG_SHOW_INFO) {
14414                     Log.v(TAG, "    IntentFilter:");
14415                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14416                 }
14417                 if (!intent.debugCheck()) {
14418                     Log.w(TAG, "==> For Provider " + p.info.name);
14419                 }
14420                 addFilter(intent);
14421             }
14422         }
14423 
removeProvider(PackageParser.Provider p)14424         public final void removeProvider(PackageParser.Provider p) {
14425             mProviders.remove(p.getComponentName());
14426             if (DEBUG_SHOW_INFO) {
14427                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
14428                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
14429                 Log.v(TAG, "    Class=" + p.info.name);
14430             }
14431             final int NI = p.intents.size();
14432             int j;
14433             for (j = 0; j < NI; j++) {
14434                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14435                 if (DEBUG_SHOW_INFO) {
14436                     Log.v(TAG, "    IntentFilter:");
14437                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14438                 }
14439                 removeFilter(intent);
14440             }
14441         }
14442 
14443         @Override
allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)14444         protected boolean allowFilterResult(
14445                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
14446             ProviderInfo filterPi = filter.provider.info;
14447             for (int i = dest.size() - 1; i >= 0; i--) {
14448                 ProviderInfo destPi = dest.get(i).providerInfo;
14449                 if (destPi.name == filterPi.name
14450                         && destPi.packageName == filterPi.packageName) {
14451                     return false;
14452                 }
14453             }
14454             return true;
14455         }
14456 
14457         @Override
newArray(int size)14458         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
14459             return new PackageParser.ProviderIntentInfo[size];
14460         }
14461 
14462         @Override
isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)14463         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
14464             if (!sUserManager.exists(userId))
14465                 return true;
14466             PackageParser.Package p = filter.provider.owner;
14467             if (p != null) {
14468                 PackageSetting ps = (PackageSetting) p.mExtras;
14469                 if (ps != null) {
14470                     // System apps are never considered stopped for purposes of
14471                     // filtering, because there may be no way for the user to
14472                     // actually re-launch them.
14473                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14474                             && ps.getStopped(userId);
14475                 }
14476             }
14477             return false;
14478         }
14479 
14480         @Override
isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)14481         protected boolean isPackageForFilter(String packageName,
14482                 PackageParser.ProviderIntentInfo info) {
14483             return packageName.equals(info.provider.owner.packageName);
14484         }
14485 
14486         @Override
newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)14487         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
14488                 int match, int userId) {
14489             if (!sUserManager.exists(userId))
14490                 return null;
14491             final PackageParser.ProviderIntentInfo info = filter;
14492             if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
14493                 return null;
14494             }
14495             final PackageParser.Provider provider = info.provider;
14496             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
14497             if (ps == null) {
14498                 return null;
14499             }
14500             final PackageUserState userState = ps.readUserState(userId);
14501             final boolean matchVisibleToInstantApp =
14502                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14503             final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14504             // throw out filters that aren't visible to instant applications
14505             if (matchVisibleToInstantApp
14506                     && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14507                 return null;
14508             }
14509             // throw out instant application filters if we're not explicitly requesting them
14510             if (!isInstantApp && userState.instantApp) {
14511                 return null;
14512             }
14513             // throw out instant application filters if updates are available; will trigger
14514             // instant application resolution
14515             if (userState.instantApp && ps.isUpdateAvailable()) {
14516                 return null;
14517             }
14518             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
14519                     userState, userId);
14520             if (pi == null) {
14521                 return null;
14522             }
14523             final ResolveInfo res = new ResolveInfo();
14524             res.providerInfo = pi;
14525             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
14526                 res.filter = filter;
14527             }
14528             res.priority = info.getPriority();
14529             res.preferredOrder = provider.owner.mPreferredOrder;
14530             res.match = match;
14531             res.isDefault = info.hasDefault;
14532             res.labelRes = info.labelRes;
14533             res.nonLocalizedLabel = info.nonLocalizedLabel;
14534             res.icon = info.icon;
14535             res.system = res.providerInfo.applicationInfo.isSystemApp();
14536             return res;
14537         }
14538 
14539         @Override
sortResults(List<ResolveInfo> results)14540         protected void sortResults(List<ResolveInfo> results) {
14541             Collections.sort(results, mResolvePrioritySorter);
14542         }
14543 
14544         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)14545         protected void dumpFilter(PrintWriter out, String prefix,
14546                 PackageParser.ProviderIntentInfo filter) {
14547             out.print(prefix);
14548             out.print(
14549                     Integer.toHexString(System.identityHashCode(filter.provider)));
14550             out.print(' ');
14551             filter.provider.printComponentShortName(out);
14552             out.print(" filter ");
14553             out.println(Integer.toHexString(System.identityHashCode(filter)));
14554         }
14555 
14556         @Override
filterToLabel(PackageParser.ProviderIntentInfo filter)14557         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
14558             return filter.provider;
14559         }
14560 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)14561         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14562             PackageParser.Provider provider = (PackageParser.Provider)label;
14563             out.print(prefix); out.print(
14564                     Integer.toHexString(System.identityHashCode(provider)));
14565                     out.print(' ');
14566                     provider.printComponentShortName(out);
14567             if (count > 1) {
14568                 out.print(" ("); out.print(count); out.print(" filters)");
14569             }
14570             out.println();
14571         }
14572 
14573         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
14574                 = new ArrayMap<ComponentName, PackageParser.Provider>();
14575         private int mFlags;
14576     }
14577 
14578     static final class EphemeralIntentResolver
14579             extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
14580         /**
14581          * The result that has the highest defined order. Ordering applies on a
14582          * per-package basis. Mapping is from package name to Pair of order and
14583          * EphemeralResolveInfo.
14584          * <p>
14585          * NOTE: This is implemented as a field variable for convenience and efficiency.
14586          * By having a field variable, we're able to track filter ordering as soon as
14587          * a non-zero order is defined. Otherwise, multiple loops across the result set
14588          * would be needed to apply ordering. If the intent resolver becomes re-entrant,
14589          * this needs to be contained entirely within {@link #filterResults}.
14590          */
14591         final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
14592 
14593         @Override
newArray(int size)14594         protected AuxiliaryResolveInfo[] newArray(int size) {
14595             return new AuxiliaryResolveInfo[size];
14596         }
14597 
14598         @Override
isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj)14599         protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
14600             return true;
14601         }
14602 
14603         @Override
newResult(AuxiliaryResolveInfo responseObj, int match, int userId)14604         protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
14605                 int userId) {
14606             if (!sUserManager.exists(userId)) {
14607                 return null;
14608             }
14609             final String packageName = responseObj.resolveInfo.getPackageName();
14610             final Integer order = responseObj.getOrder();
14611             final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
14612                     mOrderResult.get(packageName);
14613             // ordering is enabled and this item's order isn't high enough
14614             if (lastOrderResult != null && lastOrderResult.first >= order) {
14615                 return null;
14616             }
14617             final InstantAppResolveInfo res = responseObj.resolveInfo;
14618             if (order > 0) {
14619                 // non-zero order, enable ordering
14620                 mOrderResult.put(packageName, new Pair<>(order, res));
14621             }
14622             return responseObj;
14623         }
14624 
14625         @Override
filterResults(List<AuxiliaryResolveInfo> results)14626         protected void filterResults(List<AuxiliaryResolveInfo> results) {
14627             // only do work if ordering is enabled [most of the time it won't be]
14628             if (mOrderResult.size() == 0) {
14629                 return;
14630             }
14631             int resultSize = results.size();
14632             for (int i = 0; i < resultSize; i++) {
14633                 final InstantAppResolveInfo info = results.get(i).resolveInfo;
14634                 final String packageName = info.getPackageName();
14635                 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
14636                 if (savedInfo == null) {
14637                     // package doesn't having ordering
14638                     continue;
14639                 }
14640                 if (savedInfo.second == info) {
14641                     // circled back to the highest ordered item; remove from order list
14642                     mOrderResult.remove(packageName);
14643                     if (mOrderResult.size() == 0) {
14644                         // no more ordered items
14645                         break;
14646                     }
14647                     continue;
14648                 }
14649                 // item has a worse order, remove it from the result list
14650                 results.remove(i);
14651                 resultSize--;
14652                 i--;
14653             }
14654         }
14655     }
14656 
14657     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
14658             new Comparator<ResolveInfo>() {
14659         public int compare(ResolveInfo r1, ResolveInfo r2) {
14660             int v1 = r1.priority;
14661             int v2 = r2.priority;
14662             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
14663             if (v1 != v2) {
14664                 return (v1 > v2) ? -1 : 1;
14665             }
14666             v1 = r1.preferredOrder;
14667             v2 = r2.preferredOrder;
14668             if (v1 != v2) {
14669                 return (v1 > v2) ? -1 : 1;
14670             }
14671             if (r1.isDefault != r2.isDefault) {
14672                 return r1.isDefault ? -1 : 1;
14673             }
14674             v1 = r1.match;
14675             v2 = r2.match;
14676             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
14677             if (v1 != v2) {
14678                 return (v1 > v2) ? -1 : 1;
14679             }
14680             if (r1.system != r2.system) {
14681                 return r1.system ? -1 : 1;
14682             }
14683             if (r1.activityInfo != null) {
14684                 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
14685             }
14686             if (r1.serviceInfo != null) {
14687                 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
14688             }
14689             if (r1.providerInfo != null) {
14690                 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
14691             }
14692             return 0;
14693         }
14694     };
14695 
14696     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
14697             new Comparator<ProviderInfo>() {
14698         public int compare(ProviderInfo p1, ProviderInfo p2) {
14699             final int v1 = p1.initOrder;
14700             final int v2 = p2.initOrder;
14701             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
14702         }
14703     };
14704 
sendPackageBroadcast(final String action, final String pkg, final Bundle extras, final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, final int[] userIds)14705     public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
14706             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
14707             final int[] userIds) {
14708         mHandler.post(new Runnable() {
14709             @Override
14710             public void run() {
14711                 try {
14712                     final IActivityManager am = ActivityManager.getService();
14713                     if (am == null) return;
14714                     final int[] resolvedUserIds;
14715                     if (userIds == null) {
14716                         resolvedUserIds = am.getRunningUserIds();
14717                     } else {
14718                         resolvedUserIds = userIds;
14719                     }
14720                     for (int id : resolvedUserIds) {
14721                         final Intent intent = new Intent(action,
14722                                 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14723                         if (extras != null) {
14724                             intent.putExtras(extras);
14725                         }
14726                         if (targetPkg != null) {
14727                             intent.setPackage(targetPkg);
14728                         }
14729                         // Modify the UID when posting to other users
14730                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14731                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
14732                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14733                             intent.putExtra(Intent.EXTRA_UID, uid);
14734                         }
14735                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14736                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14737                         if (DEBUG_BROADCASTS) {
14738                             RuntimeException here = new RuntimeException("here");
14739                             here.fillInStackTrace();
14740                             Slog.d(TAG, "Sending to user " + id + ": "
14741                                     + intent.toShortString(false, true, false, false)
14742                                     + " " + intent.getExtras(), here);
14743                         }
14744                         am.broadcastIntent(null, intent, null, finishedReceiver,
14745                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
14746                                 null, finishedReceiver != null, false, id);
14747                     }
14748                 } catch (RemoteException ex) {
14749                 }
14750             }
14751         });
14752     }
14753 
14754     /**
14755      * Check if the external storage media is available. This is true if there
14756      * is a mounted external storage medium or if the external storage is
14757      * emulated.
14758      */
isExternalMediaAvailable()14759     private boolean isExternalMediaAvailable() {
14760         return mMediaMounted || Environment.isExternalStorageEmulated();
14761     }
14762 
14763     @Override
nextPackageToClean(PackageCleanItem lastPackage)14764     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14765         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14766             return null;
14767         }
14768         // writer
14769         synchronized (mPackages) {
14770             if (!isExternalMediaAvailable()) {
14771                 // If the external storage is no longer mounted at this point,
14772                 // the caller may not have been able to delete all of this
14773                 // packages files and can not delete any more.  Bail.
14774                 return null;
14775             }
14776             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14777             if (lastPackage != null) {
14778                 pkgs.remove(lastPackage);
14779             }
14780             if (pkgs.size() > 0) {
14781                 return pkgs.get(0);
14782             }
14783         }
14784         return null;
14785     }
14786 
schedulePackageCleaning(String packageName, int userId, boolean andCode)14787     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14788         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14789                 userId, andCode ? 1 : 0, packageName);
14790         if (mSystemReady) {
14791             msg.sendToTarget();
14792         } else {
14793             if (mPostSystemReadyMessages == null) {
14794                 mPostSystemReadyMessages = new ArrayList<>();
14795             }
14796             mPostSystemReadyMessages.add(msg);
14797         }
14798     }
14799 
startCleaningPackages()14800     void startCleaningPackages() {
14801         // reader
14802         if (!isExternalMediaAvailable()) {
14803             return;
14804         }
14805         synchronized (mPackages) {
14806             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14807                 return;
14808             }
14809         }
14810         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14811         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14812         IActivityManager am = ActivityManager.getService();
14813         if (am != null) {
14814             int dcsUid = -1;
14815             synchronized (mPackages) {
14816                 if (!mDefaultContainerWhitelisted) {
14817                     mDefaultContainerWhitelisted = true;
14818                     PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14819                     dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14820                 }
14821             }
14822             try {
14823                 if (dcsUid > 0) {
14824                     am.backgroundWhitelistUid(dcsUid);
14825                 }
14826                 am.startService(null, intent, null, false, mContext.getOpPackageName(),
14827                         UserHandle.USER_SYSTEM);
14828             } catch (RemoteException e) {
14829             }
14830         }
14831     }
14832 
14833     @Override
installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, int userId)14834     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14835             int installFlags, String installerPackageName, int userId) {
14836         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14837 
14838         final int callingUid = Binder.getCallingUid();
14839         enforceCrossUserPermission(callingUid, userId,
14840                 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14841 
14842         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14843             try {
14844                 if (observer != null) {
14845                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14846                 }
14847             } catch (RemoteException re) {
14848             }
14849             return;
14850         }
14851 
14852         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14853             installFlags |= PackageManager.INSTALL_FROM_ADB;
14854 
14855         } else {
14856             // Caller holds INSTALL_PACKAGES permission, so we're less strict
14857             // about installerPackageName.
14858 
14859             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14860             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14861         }
14862 
14863         UserHandle user;
14864         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14865             user = UserHandle.ALL;
14866         } else {
14867             user = new UserHandle(userId);
14868         }
14869 
14870         // Only system components can circumvent runtime permissions when installing.
14871         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14872                 && mContext.checkCallingOrSelfPermission(Manifest.permission
14873                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14874             throw new SecurityException("You need the "
14875                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14876                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14877         }
14878 
14879         if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14880                 || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14881             throw new IllegalArgumentException(
14882                     "New installs into ASEC containers no longer supported");
14883         }
14884 
14885         final File originFile = new File(originPath);
14886         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14887 
14888         final Message msg = mHandler.obtainMessage(INIT_COPY);
14889         final VerificationInfo verificationInfo = new VerificationInfo(
14890                 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14891         final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14892                 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14893                 null /*packageAbiOverride*/, null /*grantedPermissions*/,
14894                 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14895         params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14896         msg.obj = params;
14897 
14898         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14899                 System.identityHashCode(msg.obj));
14900         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14901                 System.identityHashCode(msg.obj));
14902 
14903         mHandler.sendMessage(msg);
14904     }
14905 
14906 
14907     /**
14908      * Ensure that the install reason matches what we know about the package installer (e.g. whether
14909      * it is acting on behalf on an enterprise or the user).
14910      *
14911      * Note that the ordering of the conditionals in this method is important. The checks we perform
14912      * are as follows, in this order:
14913      *
14914      * 1) If the install is being performed by a system app, we can trust the app to have set the
14915      *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14916      *    what it is.
14917      * 2) If the install is being performed by a device or profile owner app, the install reason
14918      *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14919      *    set the install reason correctly. If the app targets an older SDK version where install
14920      *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14921      *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14922      * 3) In all other cases, the install is being performed by a regular app that is neither part
14923      *    of the system nor a device or profile owner. We have no reason to believe that this app is
14924      *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14925      *    set to enterprise policy and if so, change it to unknown instead.
14926      */
fixUpInstallReason(String installerPackageName, int installerUid, int installReason)14927     private int fixUpInstallReason(String installerPackageName, int installerUid,
14928             int installReason) {
14929         if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14930                 == PERMISSION_GRANTED) {
14931             // If the install is being performed by a system app, we trust that app to have set the
14932             // install reason correctly.
14933             return installReason;
14934         }
14935 
14936         final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14937             ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14938         if (dpm != null) {
14939             ComponentName owner = null;
14940             try {
14941                 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14942                 if (owner == null) {
14943                     owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14944                 }
14945             } catch (RemoteException e) {
14946             }
14947             if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14948                 // If the install is being performed by a device or profile owner, the install
14949                 // reason should be enterprise policy.
14950                 return PackageManager.INSTALL_REASON_POLICY;
14951             }
14952         }
14953 
14954         if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14955             // If the install is being performed by a regular app (i.e. neither system app nor
14956             // device or profile owner), we have no reason to believe that the app is acting on
14957             // behalf of an enterprise. If the app set the install reason to enterprise policy,
14958             // change it to unknown instead.
14959             return PackageManager.INSTALL_REASON_UNKNOWN;
14960         }
14961 
14962         // If the install is being performed by a regular app and the install reason was set to any
14963         // value but enterprise policy, leave the install reason unchanged.
14964         return installReason;
14965     }
14966 
installStage(String packageName, File stagedDir, String stagedCid, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, String installerPackageName, int installerUid, UserHandle user, Certificate[][] certificates)14967     void installStage(String packageName, File stagedDir, String stagedCid,
14968             IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14969             String installerPackageName, int installerUid, UserHandle user,
14970             Certificate[][] certificates) {
14971         if (DEBUG_EPHEMERAL) {
14972             if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14973                 Slog.d(TAG, "Ephemeral install of " + packageName);
14974             }
14975         }
14976         final VerificationInfo verificationInfo = new VerificationInfo(
14977                 sessionParams.originatingUri, sessionParams.referrerUri,
14978                 sessionParams.originatingUid, installerUid);
14979 
14980         final OriginInfo origin;
14981         if (stagedDir != null) {
14982             origin = OriginInfo.fromStagedFile(stagedDir);
14983         } else {
14984             origin = OriginInfo.fromStagedContainer(stagedCid);
14985         }
14986 
14987         final Message msg = mHandler.obtainMessage(INIT_COPY);
14988         final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14989                 sessionParams.installReason);
14990         final InstallParams params = new InstallParams(origin, null, observer,
14991                 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14992                 verificationInfo, user, sessionParams.abiOverride,
14993                 sessionParams.grantedRuntimePermissions, certificates, installReason);
14994         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14995         msg.obj = params;
14996 
14997         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14998                 System.identityHashCode(msg.obj));
14999         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
15000                 System.identityHashCode(msg.obj));
15001 
15002         mHandler.sendMessage(msg);
15003     }
15004 
sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)15005     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
15006             int userId) {
15007         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
15008         sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
15009                 false /*startReceiver*/, pkgSetting.appId, userId);
15010 
15011         // Send a session commit broadcast
15012         final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
15013         info.installReason = pkgSetting.getInstallReason(userId);
15014         info.appPackageName = packageName;
15015         sendSessionCommitBroadcast(info, userId);
15016     }
15017 
sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted, boolean includeStopped, int appId, int... userIds)15018     public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
15019             boolean includeStopped, int appId, int... userIds) {
15020         if (ArrayUtils.isEmpty(userIds)) {
15021             return;
15022         }
15023         Bundle extras = new Bundle(1);
15024         // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
15025         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
15026 
15027         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
15028                 packageName, extras, 0, null, null, userIds);
15029         if (sendBootCompleted) {
15030             mHandler.post(() -> {
15031                         for (int userId : userIds) {
15032                             sendBootCompletedBroadcastToSystemApp(
15033                                     packageName, includeStopped, userId);
15034                         }
15035                     }
15036             );
15037         }
15038     }
15039 
15040     /**
15041      * The just-installed/enabled app is bundled on the system, so presumed to be able to run
15042      * automatically without needing an explicit launch.
15043      * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
15044      */
sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped, int userId)15045     private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
15046             int userId) {
15047         // If user is not running, the app didn't miss any broadcast
15048         if (!mUserManagerInternal.isUserRunning(userId)) {
15049             return;
15050         }
15051         final IActivityManager am = ActivityManager.getService();
15052         try {
15053             // Deliver LOCKED_BOOT_COMPLETED first
15054             Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
15055                     .setPackage(packageName);
15056             if (includeStopped) {
15057                 lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15058             }
15059             final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
15060             am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
15061                     android.app.AppOpsManager.OP_NONE, null, false, false, userId);
15062 
15063             // Deliver BOOT_COMPLETED only if user is unlocked
15064             if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
15065                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
15066                 if (includeStopped) {
15067                     bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15068                 }
15069                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
15070                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
15071             }
15072         } catch (RemoteException e) {
15073             throw e.rethrowFromSystemServer();
15074         }
15075     }
15076 
15077     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)15078     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
15079             int userId) {
15080         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15081         PackageSetting pkgSetting;
15082         final int callingUid = Binder.getCallingUid();
15083         enforceCrossUserPermission(callingUid, userId,
15084                 true /* requireFullPermission */, true /* checkShell */,
15085                 "setApplicationHiddenSetting for user " + userId);
15086 
15087         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
15088             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
15089             return false;
15090         }
15091 
15092         long callingId = Binder.clearCallingIdentity();
15093         try {
15094             boolean sendAdded = false;
15095             boolean sendRemoved = false;
15096             // writer
15097             synchronized (mPackages) {
15098                 pkgSetting = mSettings.mPackages.get(packageName);
15099                 if (pkgSetting == null) {
15100                     return false;
15101                 }
15102                 if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15103                     return false;
15104                 }
15105                 // Do not allow "android" is being disabled
15106                 if ("android".equals(packageName)) {
15107                     Slog.w(TAG, "Cannot hide package: android");
15108                     return false;
15109                 }
15110                 // Cannot hide static shared libs as they are considered
15111                 // a part of the using app (emulating static linking). Also
15112                 // static libs are installed always on internal storage.
15113                 PackageParser.Package pkg = mPackages.get(packageName);
15114                 if (pkg != null && pkg.staticSharedLibName != null) {
15115                     Slog.w(TAG, "Cannot hide package: " + packageName
15116                             + " providing static shared library: "
15117                             + pkg.staticSharedLibName);
15118                     return false;
15119                 }
15120                 // Only allow protected packages to hide themselves.
15121                 if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
15122                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15123                     Slog.w(TAG, "Not hiding protected package: " + packageName);
15124                     return false;
15125                 }
15126 
15127                 if (pkgSetting.getHidden(userId) != hidden) {
15128                     pkgSetting.setHidden(hidden, userId);
15129                     mSettings.writePackageRestrictionsLPr(userId);
15130                     if (hidden) {
15131                         sendRemoved = true;
15132                     } else {
15133                         sendAdded = true;
15134                     }
15135                 }
15136             }
15137             if (sendAdded) {
15138                 sendPackageAddedForUser(packageName, pkgSetting, userId);
15139                 return true;
15140             }
15141             if (sendRemoved) {
15142                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
15143                         "hiding pkg");
15144                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
15145                 return true;
15146             }
15147         } finally {
15148             Binder.restoreCallingIdentity(callingId);
15149         }
15150         return false;
15151     }
15152 
sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)15153     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
15154             int userId) {
15155         final PackageRemovedInfo info = new PackageRemovedInfo(this);
15156         info.removedPackage = packageName;
15157         info.installerPackageName = pkgSetting.installerPackageName;
15158         info.removedUsers = new int[] {userId};
15159         info.broadcastUsers = new int[] {userId};
15160         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
15161         info.sendPackageRemovedBroadcasts(true /*killApp*/);
15162     }
15163 
sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended)15164     private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
15165         if (pkgList.length > 0) {
15166             Bundle extras = new Bundle(1);
15167             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
15168 
15169             sendPackageBroadcast(
15170                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
15171                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
15172                     null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
15173                     new int[] {userId});
15174         }
15175     }
15176 
15177     /**
15178      * Returns true if application is not found or there was an error. Otherwise it returns
15179      * the hidden state of the package for the given user.
15180      */
15181     @Override
getApplicationHiddenSettingAsUser(String packageName, int userId)15182     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
15183         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15184         final int callingUid = Binder.getCallingUid();
15185         enforceCrossUserPermission(callingUid, userId,
15186                 true /* requireFullPermission */, false /* checkShell */,
15187                 "getApplicationHidden for user " + userId);
15188         PackageSetting ps;
15189         long callingId = Binder.clearCallingIdentity();
15190         try {
15191             // writer
15192             synchronized (mPackages) {
15193                 ps = mSettings.mPackages.get(packageName);
15194                 if (ps == null) {
15195                     return true;
15196                 }
15197                 if (filterAppAccessLPr(ps, callingUid, userId)) {
15198                     return true;
15199                 }
15200                 return ps.getHidden(userId);
15201             }
15202         } finally {
15203             Binder.restoreCallingIdentity(callingId);
15204         }
15205     }
15206 
15207     /**
15208      * @hide
15209      */
15210     @Override
installExistingPackageAsUser(String packageName, int userId, int installFlags, int installReason)15211     public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
15212             int installReason) {
15213         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
15214                 null);
15215         PackageSetting pkgSetting;
15216         final int callingUid = Binder.getCallingUid();
15217         enforceCrossUserPermission(callingUid, userId,
15218                 true /* requireFullPermission */, true /* checkShell */,
15219                 "installExistingPackage for user " + userId);
15220         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
15221             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
15222         }
15223 
15224         long callingId = Binder.clearCallingIdentity();
15225         try {
15226             boolean installed = false;
15227             final boolean instantApp =
15228                     (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15229             final boolean fullApp =
15230                     (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
15231 
15232             // writer
15233             synchronized (mPackages) {
15234                 pkgSetting = mSettings.mPackages.get(packageName);
15235                 if (pkgSetting == null) {
15236                     return PackageManager.INSTALL_FAILED_INVALID_URI;
15237                 }
15238                 if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
15239                     // only allow the existing package to be used if it's installed as a full
15240                     // application for at least one user
15241                     boolean installAllowed = false;
15242                     for (int checkUserId : sUserManager.getUserIds()) {
15243                         installAllowed = !pkgSetting.getInstantApp(checkUserId);
15244                         if (installAllowed) {
15245                             break;
15246                         }
15247                     }
15248                     if (!installAllowed) {
15249                         return PackageManager.INSTALL_FAILED_INVALID_URI;
15250                     }
15251                 }
15252                 if (!pkgSetting.getInstalled(userId)) {
15253                     pkgSetting.setInstalled(true, userId);
15254                     pkgSetting.setHidden(false, userId);
15255                     pkgSetting.setInstallReason(installReason, userId);
15256                     mSettings.writePackageRestrictionsLPr(userId);
15257                     mSettings.writeKernelMappingLPr(pkgSetting);
15258                     installed = true;
15259                 } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15260                     // upgrade app from instant to full; we don't allow app downgrade
15261                     installed = true;
15262                 }
15263                 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
15264             }
15265 
15266             if (installed) {
15267                 if (pkgSetting.pkg != null) {
15268                     synchronized (mInstallLock) {
15269                         // We don't need to freeze for a brand new install
15270                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
15271                     }
15272                 }
15273                 sendPackageAddedForUser(packageName, pkgSetting, userId);
15274                 synchronized (mPackages) {
15275                     updateSequenceNumberLP(pkgSetting, new int[]{ userId });
15276                 }
15277             }
15278         } finally {
15279             Binder.restoreCallingIdentity(callingId);
15280         }
15281 
15282         return PackageManager.INSTALL_SUCCEEDED;
15283     }
15284 
setInstantAppForUser(PackageSetting pkgSetting, int userId, boolean instantApp, boolean fullApp)15285     void setInstantAppForUser(PackageSetting pkgSetting, int userId,
15286             boolean instantApp, boolean fullApp) {
15287         // no state specified; do nothing
15288         if (!instantApp && !fullApp) {
15289             return;
15290         }
15291         if (userId != UserHandle.USER_ALL) {
15292             if (instantApp && !pkgSetting.getInstantApp(userId)) {
15293                 pkgSetting.setInstantApp(true /*instantApp*/, userId);
15294             } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15295                 pkgSetting.setInstantApp(false /*instantApp*/, userId);
15296             }
15297         } else {
15298             for (int currentUserId : sUserManager.getUserIds()) {
15299                 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
15300                     pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
15301                 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
15302                     pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
15303                 }
15304             }
15305         }
15306     }
15307 
isUserRestricted(int userId, String restrictionKey)15308     boolean isUserRestricted(int userId, String restrictionKey) {
15309         Bundle restrictions = sUserManager.getUserRestrictions(userId);
15310         if (restrictions.getBoolean(restrictionKey, false)) {
15311             Log.w(TAG, "User is restricted: " + restrictionKey);
15312             return true;
15313         }
15314         return false;
15315     }
15316 
15317     @Override
setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, int userId)15318     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
15319             int userId) {
15320         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15321         final int callingUid = Binder.getCallingUid();
15322         enforceCrossUserPermission(callingUid, userId,
15323                 true /* requireFullPermission */, true /* checkShell */,
15324                 "setPackagesSuspended for user " + userId);
15325 
15326         if (ArrayUtils.isEmpty(packageNames)) {
15327             return packageNames;
15328         }
15329 
15330         // List of package names for whom the suspended state has changed.
15331         List<String> changedPackages = new ArrayList<>(packageNames.length);
15332         // List of package names for whom the suspended state is not set as requested in this
15333         // method.
15334         List<String> unactionedPackages = new ArrayList<>(packageNames.length);
15335         long callingId = Binder.clearCallingIdentity();
15336         try {
15337             for (int i = 0; i < packageNames.length; i++) {
15338                 String packageName = packageNames[i];
15339                 boolean changed = false;
15340                 final int appId;
15341                 synchronized (mPackages) {
15342                     final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
15343                     if (pkgSetting == null
15344                             || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15345                         Slog.w(TAG, "Could not find package setting for package \"" + packageName
15346                                 + "\". Skipping suspending/un-suspending.");
15347                         unactionedPackages.add(packageName);
15348                         continue;
15349                     }
15350                     appId = pkgSetting.appId;
15351                     if (pkgSetting.getSuspended(userId) != suspended) {
15352                         if (!canSuspendPackageForUserLocked(packageName, userId)) {
15353                             unactionedPackages.add(packageName);
15354                             continue;
15355                         }
15356                         pkgSetting.setSuspended(suspended, userId);
15357                         mSettings.writePackageRestrictionsLPr(userId);
15358                         changed = true;
15359                         changedPackages.add(packageName);
15360                     }
15361                 }
15362 
15363                 if (changed && suspended) {
15364                     killApplication(packageName, UserHandle.getUid(userId, appId),
15365                             "suspending package");
15366                 }
15367             }
15368         } finally {
15369             Binder.restoreCallingIdentity(callingId);
15370         }
15371 
15372         if (!changedPackages.isEmpty()) {
15373             sendPackagesSuspendedForUser(changedPackages.toArray(
15374                     new String[changedPackages.size()]), userId, suspended);
15375         }
15376 
15377         return unactionedPackages.toArray(new String[unactionedPackages.size()]);
15378     }
15379 
15380     @Override
isPackageSuspendedForUser(String packageName, int userId)15381     public boolean isPackageSuspendedForUser(String packageName, int userId) {
15382         final int callingUid = Binder.getCallingUid();
15383         enforceCrossUserPermission(callingUid, userId,
15384                 true /* requireFullPermission */, false /* checkShell */,
15385                 "isPackageSuspendedForUser for user " + userId);
15386         synchronized (mPackages) {
15387             final PackageSetting ps = mSettings.mPackages.get(packageName);
15388             if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
15389                 throw new IllegalArgumentException("Unknown target package: " + packageName);
15390             }
15391             return ps.getSuspended(userId);
15392         }
15393     }
15394 
canSuspendPackageForUserLocked(String packageName, int userId)15395     private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
15396         if (isPackageDeviceAdmin(packageName, userId)) {
15397             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15398                     + "\": has an active device admin");
15399             return false;
15400         }
15401 
15402         String activeLauncherPackageName = getActiveLauncherPackageName(userId);
15403         if (packageName.equals(activeLauncherPackageName)) {
15404             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15405                     + "\": contains the active launcher");
15406             return false;
15407         }
15408 
15409         if (packageName.equals(mRequiredInstallerPackage)) {
15410             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15411                     + "\": required for package installation");
15412             return false;
15413         }
15414 
15415         if (packageName.equals(mRequiredUninstallerPackage)) {
15416             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15417                     + "\": required for package uninstallation");
15418             return false;
15419         }
15420 
15421         if (packageName.equals(mRequiredVerifierPackage)) {
15422             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15423                     + "\": required for package verification");
15424             return false;
15425         }
15426 
15427         if (packageName.equals(getDefaultDialerPackageName(userId))) {
15428             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15429                     + "\": is the default dialer");
15430             return false;
15431         }
15432 
15433         if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15434             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15435                     + "\": protected package");
15436             return false;
15437         }
15438 
15439         // Cannot suspend static shared libs as they are considered
15440         // a part of the using app (emulating static linking). Also
15441         // static libs are installed always on internal storage.
15442         PackageParser.Package pkg = mPackages.get(packageName);
15443         if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
15444             Slog.w(TAG, "Cannot suspend package: " + packageName
15445                     + " providing static shared library: "
15446                     + pkg.staticSharedLibName);
15447             return false;
15448         }
15449 
15450         return true;
15451     }
15452 
getActiveLauncherPackageName(int userId)15453     private String getActiveLauncherPackageName(int userId) {
15454         Intent intent = new Intent(Intent.ACTION_MAIN);
15455         intent.addCategory(Intent.CATEGORY_HOME);
15456         ResolveInfo resolveInfo = resolveIntent(
15457                 intent,
15458                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
15459                 PackageManager.MATCH_DEFAULT_ONLY,
15460                 userId);
15461 
15462         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
15463     }
15464 
getDefaultDialerPackageName(int userId)15465     private String getDefaultDialerPackageName(int userId) {
15466         synchronized (mPackages) {
15467             return mSettings.getDefaultDialerPackageNameLPw(userId);
15468         }
15469     }
15470 
15471     @Override
verifyPendingInstall(int id, int verificationCode)15472     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
15473         mContext.enforceCallingOrSelfPermission(
15474                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15475                 "Only package verification agents can verify applications");
15476 
15477         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15478         final PackageVerificationResponse response = new PackageVerificationResponse(
15479                 verificationCode, Binder.getCallingUid());
15480         msg.arg1 = id;
15481         msg.obj = response;
15482         mHandler.sendMessage(msg);
15483     }
15484 
15485     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)15486     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
15487             long millisecondsToDelay) {
15488         mContext.enforceCallingOrSelfPermission(
15489                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15490                 "Only package verification agents can extend verification timeouts");
15491 
15492         final PackageVerificationState state = mPendingVerification.get(id);
15493         final PackageVerificationResponse response = new PackageVerificationResponse(
15494                 verificationCodeAtTimeout, Binder.getCallingUid());
15495 
15496         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
15497             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
15498         }
15499         if (millisecondsToDelay < 0) {
15500             millisecondsToDelay = 0;
15501         }
15502         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
15503                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
15504             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
15505         }
15506 
15507         if ((state != null) && !state.timeoutExtended()) {
15508             state.extendTimeout();
15509 
15510             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15511             msg.arg1 = id;
15512             msg.obj = response;
15513             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
15514         }
15515     }
15516 
broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)15517     private void broadcastPackageVerified(int verificationId, Uri packageUri,
15518             int verificationCode, UserHandle user) {
15519         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
15520         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
15521         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15522         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15523         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
15524 
15525         mContext.sendBroadcastAsUser(intent, user,
15526                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
15527     }
15528 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)15529     private ComponentName matchComponentForVerifier(String packageName,
15530             List<ResolveInfo> receivers) {
15531         ActivityInfo targetReceiver = null;
15532 
15533         final int NR = receivers.size();
15534         for (int i = 0; i < NR; i++) {
15535             final ResolveInfo info = receivers.get(i);
15536             if (info.activityInfo == null) {
15537                 continue;
15538             }
15539 
15540             if (packageName.equals(info.activityInfo.packageName)) {
15541                 targetReceiver = info.activityInfo;
15542                 break;
15543             }
15544         }
15545 
15546         if (targetReceiver == null) {
15547             return null;
15548         }
15549 
15550         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
15551     }
15552 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)15553     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
15554             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
15555         if (pkgInfo.verifiers.length == 0) {
15556             return null;
15557         }
15558 
15559         final int N = pkgInfo.verifiers.length;
15560         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
15561         for (int i = 0; i < N; i++) {
15562             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
15563 
15564             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
15565                     receivers);
15566             if (comp == null) {
15567                 continue;
15568             }
15569 
15570             final int verifierUid = getUidForVerifier(verifierInfo);
15571             if (verifierUid == -1) {
15572                 continue;
15573             }
15574 
15575             if (DEBUG_VERIFY) {
15576                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
15577                         + " with the correct signature");
15578             }
15579             sufficientVerifiers.add(comp);
15580             verificationState.addSufficientVerifier(verifierUid);
15581         }
15582 
15583         return sufficientVerifiers;
15584     }
15585 
getUidForVerifier(VerifierInfo verifierInfo)15586     private int getUidForVerifier(VerifierInfo verifierInfo) {
15587         synchronized (mPackages) {
15588             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
15589             if (pkg == null) {
15590                 return -1;
15591             } else if (pkg.mSignatures.length != 1) {
15592                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15593                         + " has more than one signature; ignoring");
15594                 return -1;
15595             }
15596 
15597             /*
15598              * If the public key of the package's signature does not match
15599              * our expected public key, then this is a different package and
15600              * we should skip.
15601              */
15602 
15603             final byte[] expectedPublicKey;
15604             try {
15605                 final Signature verifierSig = pkg.mSignatures[0];
15606                 final PublicKey publicKey = verifierSig.getPublicKey();
15607                 expectedPublicKey = publicKey.getEncoded();
15608             } catch (CertificateException e) {
15609                 return -1;
15610             }
15611 
15612             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
15613 
15614             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
15615                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15616                         + " does not have the expected public key; ignoring");
15617                 return -1;
15618             }
15619 
15620             return pkg.applicationInfo.uid;
15621         }
15622     }
15623 
15624     @Override
finishPackageInstall(int token, boolean didLaunch)15625     public void finishPackageInstall(int token, boolean didLaunch) {
15626         enforceSystemOrRoot("Only the system is allowed to finish installs");
15627 
15628         if (DEBUG_INSTALL) {
15629             Slog.v(TAG, "BM finishing package install for " + token);
15630         }
15631         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15632 
15633         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
15634         mHandler.sendMessage(msg);
15635     }
15636 
15637     /**
15638      * Get the verification agent timeout.  Used for both the APK verifier and the
15639      * intent filter verifier.
15640      *
15641      * @return verification timeout in milliseconds
15642      */
getVerificationTimeout()15643     private long getVerificationTimeout() {
15644         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
15645                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
15646                 DEFAULT_VERIFICATION_TIMEOUT);
15647     }
15648 
15649     /**
15650      * Get the default verification agent response code.
15651      *
15652      * @return default verification response code
15653      */
getDefaultVerificationResponse(UserHandle user)15654     private int getDefaultVerificationResponse(UserHandle user) {
15655         if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
15656             return PackageManager.VERIFICATION_REJECT;
15657         }
15658         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15659                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
15660                 DEFAULT_VERIFICATION_RESPONSE);
15661     }
15662 
15663     /**
15664      * Check whether or not package verification has been enabled.
15665      *
15666      * @return true if verification should be performed
15667      */
isVerificationEnabled(int userId, int installFlags, int installerUid)15668     private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
15669         if (!DEFAULT_VERIFY_ENABLE) {
15670             return false;
15671         }
15672 
15673         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
15674 
15675         // Check if installing from ADB
15676         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
15677             // Do not run verification in a test harness environment
15678             if (ActivityManager.isRunningInTestHarness()) {
15679                 return false;
15680             }
15681             if (ensureVerifyAppsEnabled) {
15682                 return true;
15683             }
15684             // Check if the developer does not want package verification for ADB installs
15685             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15686                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
15687                 return false;
15688             }
15689         } else {
15690             // only when not installed from ADB, skip verification for instant apps when
15691             // the installer and verifier are the same.
15692             if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
15693                 if (mInstantAppInstallerActivity != null
15694                         && mInstantAppInstallerActivity.packageName.equals(
15695                                 mRequiredVerifierPackage)) {
15696                     try {
15697                         mContext.getSystemService(AppOpsManager.class)
15698                                 .checkPackage(installerUid, mRequiredVerifierPackage);
15699                         if (DEBUG_VERIFY) {
15700                             Slog.i(TAG, "disable verification for instant app");
15701                         }
15702                         return false;
15703                     } catch (SecurityException ignore) { }
15704                 }
15705             }
15706         }
15707 
15708         if (ensureVerifyAppsEnabled) {
15709             return true;
15710         }
15711 
15712         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15713                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
15714     }
15715 
15716     @Override
verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)15717     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
15718             throws RemoteException {
15719         mContext.enforceCallingOrSelfPermission(
15720                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
15721                 "Only intentfilter verification agents can verify applications");
15722 
15723         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
15724         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
15725                 Binder.getCallingUid(), verificationCode, failedDomains);
15726         msg.arg1 = id;
15727         msg.obj = response;
15728         mHandler.sendMessage(msg);
15729     }
15730 
15731     @Override
getIntentVerificationStatus(String packageName, int userId)15732     public int getIntentVerificationStatus(String packageName, int userId) {
15733         final int callingUid = Binder.getCallingUid();
15734         if (UserHandle.getUserId(callingUid) != userId) {
15735             mContext.enforceCallingOrSelfPermission(
15736                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15737                     "getIntentVerificationStatus" + userId);
15738         }
15739         if (getInstantAppPackageName(callingUid) != null) {
15740             return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15741         }
15742         synchronized (mPackages) {
15743             final PackageSetting ps = mSettings.mPackages.get(packageName);
15744             if (ps == null
15745                     || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15746                 return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15747             }
15748             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15749         }
15750     }
15751 
15752     @Override
updateIntentVerificationStatus(String packageName, int status, int userId)15753     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15754         mContext.enforceCallingOrSelfPermission(
15755                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15756 
15757         boolean result = false;
15758         synchronized (mPackages) {
15759             final PackageSetting ps = mSettings.mPackages.get(packageName);
15760             if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15761                 return false;
15762             }
15763             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15764         }
15765         if (result) {
15766             scheduleWritePackageRestrictionsLocked(userId);
15767         }
15768         return result;
15769     }
15770 
15771     @Override
getIntentFilterVerifications( String packageName)15772     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15773             String packageName) {
15774         final int callingUid = Binder.getCallingUid();
15775         if (getInstantAppPackageName(callingUid) != null) {
15776             return ParceledListSlice.emptyList();
15777         }
15778         synchronized (mPackages) {
15779             final PackageSetting ps = mSettings.mPackages.get(packageName);
15780             if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15781                 return ParceledListSlice.emptyList();
15782             }
15783             return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15784         }
15785     }
15786 
15787     @Override
getAllIntentFilters(String packageName)15788     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15789         if (TextUtils.isEmpty(packageName)) {
15790             return ParceledListSlice.emptyList();
15791         }
15792         final int callingUid = Binder.getCallingUid();
15793         final int callingUserId = UserHandle.getUserId(callingUid);
15794         synchronized (mPackages) {
15795             PackageParser.Package pkg = mPackages.get(packageName);
15796             if (pkg == null || pkg.activities == null) {
15797                 return ParceledListSlice.emptyList();
15798             }
15799             if (pkg.mExtras == null) {
15800                 return ParceledListSlice.emptyList();
15801             }
15802             final PackageSetting ps = (PackageSetting) pkg.mExtras;
15803             if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15804                 return ParceledListSlice.emptyList();
15805             }
15806             final int count = pkg.activities.size();
15807             ArrayList<IntentFilter> result = new ArrayList<>();
15808             for (int n=0; n<count; n++) {
15809                 PackageParser.Activity activity = pkg.activities.get(n);
15810                 if (activity.intents != null && activity.intents.size() > 0) {
15811                     result.addAll(activity.intents);
15812                 }
15813             }
15814             return new ParceledListSlice<>(result);
15815         }
15816     }
15817 
15818     @Override
setDefaultBrowserPackageName(String packageName, int userId)15819     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15820         mContext.enforceCallingOrSelfPermission(
15821                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15822         if (UserHandle.getCallingUserId() != userId) {
15823             mContext.enforceCallingOrSelfPermission(
15824                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15825         }
15826 
15827         synchronized (mPackages) {
15828             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15829             if (packageName != null) {
15830                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15831                         packageName, userId);
15832             }
15833             return result;
15834         }
15835     }
15836 
15837     @Override
getDefaultBrowserPackageName(int userId)15838     public String getDefaultBrowserPackageName(int userId) {
15839         if (UserHandle.getCallingUserId() != userId) {
15840             mContext.enforceCallingOrSelfPermission(
15841                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15842         }
15843         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15844             return null;
15845         }
15846         synchronized (mPackages) {
15847             return mSettings.getDefaultBrowserPackageNameLPw(userId);
15848         }
15849     }
15850 
15851     /**
15852      * Get the "allow unknown sources" setting.
15853      *
15854      * @return the current "allow unknown sources" setting
15855      */
getUnknownSourcesSettings()15856     private int getUnknownSourcesSettings() {
15857         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15858                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15859                 -1);
15860     }
15861 
15862     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)15863     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15864         final int callingUid = Binder.getCallingUid();
15865         if (getInstantAppPackageName(callingUid) != null) {
15866             return;
15867         }
15868         // writer
15869         synchronized (mPackages) {
15870             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15871             if (targetPackageSetting == null
15872                     || filterAppAccessLPr(
15873                             targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15874                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15875             }
15876 
15877             PackageSetting installerPackageSetting;
15878             if (installerPackageName != null) {
15879                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15880                 if (installerPackageSetting == null) {
15881                     throw new IllegalArgumentException("Unknown installer package: "
15882                             + installerPackageName);
15883                 }
15884             } else {
15885                 installerPackageSetting = null;
15886             }
15887 
15888             Signature[] callerSignature;
15889             Object obj = mSettings.getUserIdLPr(callingUid);
15890             if (obj != null) {
15891                 if (obj instanceof SharedUserSetting) {
15892                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15893                 } else if (obj instanceof PackageSetting) {
15894                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15895                 } else {
15896                     throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15897                 }
15898             } else {
15899                 throw new SecurityException("Unknown calling UID: " + callingUid);
15900             }
15901 
15902             // Verify: can't set installerPackageName to a package that is
15903             // not signed with the same cert as the caller.
15904             if (installerPackageSetting != null) {
15905                 if (compareSignatures(callerSignature,
15906                         installerPackageSetting.signatures.mSignatures)
15907                         != PackageManager.SIGNATURE_MATCH) {
15908                     throw new SecurityException(
15909                             "Caller does not have same cert as new installer package "
15910                             + installerPackageName);
15911                 }
15912             }
15913 
15914             // Verify: if target already has an installer package, it must
15915             // be signed with the same cert as the caller.
15916             String targetInstallerPackageName =
15917                     targetPackageSetting.installerPackageName;
15918             PackageSetting targetInstallerPkgSetting = targetInstallerPackageName == null ? null :
15919                     mSettings.mPackages.get(targetInstallerPackageName);
15920 
15921             if (targetInstallerPkgSetting != null) {
15922                 if (compareSignatures(callerSignature,
15923                         targetInstallerPkgSetting.signatures.mSignatures)
15924                         != PackageManager.SIGNATURE_MATCH) {
15925                     throw new SecurityException(
15926                             "Caller does not have same cert as old installer package "
15927                                     + targetInstallerPackageName);
15928                 }
15929             } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
15930                     != PackageManager.PERMISSION_GRANTED) {
15931                 // This is probably an attempt to exploit vulnerability b/150857253 of taking
15932                 // privileged installer permissions when the installer has been uninstalled or
15933                 // was never set.
15934                 EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
15935                 return;
15936             }
15937 
15938             // Okay!
15939             targetPackageSetting.installerPackageName = installerPackageName;
15940             if (installerPackageName != null) {
15941                 mSettings.mInstallerPackages.add(installerPackageName);
15942             }
15943             scheduleWriteSettingsLocked();
15944         }
15945     }
15946 
15947     @Override
setApplicationCategoryHint(String packageName, int categoryHint, String callerPackageName)15948     public void setApplicationCategoryHint(String packageName, int categoryHint,
15949             String callerPackageName) {
15950         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15951             throw new SecurityException("Instant applications don't have access to this method");
15952         }
15953         mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15954                 callerPackageName);
15955         synchronized (mPackages) {
15956             PackageSetting ps = mSettings.mPackages.get(packageName);
15957             if (ps == null) {
15958                 throw new IllegalArgumentException("Unknown target package " + packageName);
15959             }
15960             if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15961                 throw new IllegalArgumentException("Unknown target package " + packageName);
15962             }
15963             if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15964                 throw new IllegalArgumentException("Calling package " + callerPackageName
15965                         + " is not installer for " + packageName);
15966             }
15967 
15968             if (ps.categoryHint != categoryHint) {
15969                 ps.categoryHint = categoryHint;
15970                 scheduleWriteSettingsLocked();
15971             }
15972         }
15973     }
15974 
processPendingInstall(final InstallArgs args, final int currentStatus)15975     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15976         // Queue up an async operation since the package installation may take a little while.
15977         mHandler.post(new Runnable() {
15978             public void run() {
15979                 mHandler.removeCallbacks(this);
15980                  // Result object to be returned
15981                 PackageInstalledInfo res = new PackageInstalledInfo();
15982                 res.setReturnCode(currentStatus);
15983                 res.uid = -1;
15984                 res.pkg = null;
15985                 res.removedInfo = null;
15986                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15987                     args.doPreInstall(res.returnCode);
15988                     synchronized (mInstallLock) {
15989                         installPackageTracedLI(args, res);
15990                     }
15991                     args.doPostInstall(res.returnCode, res.uid);
15992                 }
15993 
15994                 // A restore should be performed at this point if (a) the install
15995                 // succeeded, (b) the operation is not an update, and (c) the new
15996                 // package has not opted out of backup participation.
15997                 final boolean update = res.removedInfo != null
15998                         && res.removedInfo.removedPackage != null;
15999                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
16000                 boolean doRestore = !update
16001                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
16002 
16003                 // Set up the post-install work request bookkeeping.  This will be used
16004                 // and cleaned up by the post-install event handling regardless of whether
16005                 // there's a restore pass performed.  Token values are >= 1.
16006                 int token;
16007                 if (mNextInstallToken < 0) mNextInstallToken = 1;
16008                 token = mNextInstallToken++;
16009 
16010                 PostInstallData data = new PostInstallData(args, res);
16011                 mRunningInstalls.put(token, data);
16012                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
16013 
16014                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
16015                     // Pass responsibility to the Backup Manager.  It will perform a
16016                     // restore if appropriate, then pass responsibility back to the
16017                     // Package Manager to run the post-install observer callbacks
16018                     // and broadcasts.
16019                     IBackupManager bm = IBackupManager.Stub.asInterface(
16020                             ServiceManager.getService(Context.BACKUP_SERVICE));
16021                     if (bm != null) {
16022                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
16023                                 + " to BM for possible restore");
16024                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
16025                         try {
16026                             // TODO: http://b/22388012
16027                             if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
16028                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
16029                             } else {
16030                                 doRestore = false;
16031                             }
16032                         } catch (RemoteException e) {
16033                             // can't happen; the backup manager is local
16034                         } catch (Exception e) {
16035                             Slog.e(TAG, "Exception trying to enqueue restore", e);
16036                             doRestore = false;
16037                         }
16038                     } else {
16039                         Slog.e(TAG, "Backup Manager not found!");
16040                         doRestore = false;
16041                     }
16042                 }
16043 
16044                 if (!doRestore) {
16045                     // No restore possible, or the Backup Manager was mysteriously not
16046                     // available -- just fire the post-install work request directly.
16047                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
16048 
16049                     Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
16050 
16051                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
16052                     mHandler.sendMessage(msg);
16053                 }
16054             }
16055         });
16056     }
16057 
16058     /**
16059      * Callback from PackageSettings whenever an app is first transitioned out of the
16060      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
16061      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
16062      * here whether the app is the target of an ongoing install, and only send the
16063      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
16064      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
16065      * handling.
16066      */
notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId)16067     void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
16068         // Serialize this with the rest of the install-process message chain.  In the
16069         // restore-at-install case, this Runnable will necessarily run before the
16070         // POST_INSTALL message is processed, so the contents of mRunningInstalls
16071         // are coherent.  In the non-restore case, the app has already completed install
16072         // and been launched through some other means, so it is not in a problematic
16073         // state for observers to see the FIRST_LAUNCH signal.
16074         mHandler.post(new Runnable() {
16075             @Override
16076             public void run() {
16077                 for (int i = 0; i < mRunningInstalls.size(); i++) {
16078                     final PostInstallData data = mRunningInstalls.valueAt(i);
16079                     if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16080                         continue;
16081                     }
16082                     if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
16083                         // right package; but is it for the right user?
16084                         for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
16085                             if (userId == data.res.newUsers[uIndex]) {
16086                                 if (DEBUG_BACKUP) {
16087                                     Slog.i(TAG, "Package " + pkgName
16088                                             + " being restored so deferring FIRST_LAUNCH");
16089                                 }
16090                                 return;
16091                             }
16092                         }
16093                     }
16094                 }
16095                 // didn't find it, so not being restored
16096                 if (DEBUG_BACKUP) {
16097                     Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
16098                 }
16099                 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
16100             }
16101         });
16102     }
16103 
sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds)16104     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
16105         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
16106                 installerPkg, null, userIds);
16107     }
16108 
16109     private abstract class HandlerParams {
16110         private static final int MAX_RETRIES = 4;
16111 
16112         /**
16113          * Number of times startCopy() has been attempted and had a non-fatal
16114          * error.
16115          */
16116         private int mRetries = 0;
16117 
16118         /** User handle for the user requesting the information or installation. */
16119         private final UserHandle mUser;
16120         String traceMethod;
16121         int traceCookie;
16122 
HandlerParams(UserHandle user)16123         HandlerParams(UserHandle user) {
16124             mUser = user;
16125         }
16126 
getUser()16127         UserHandle getUser() {
16128             return mUser;
16129         }
16130 
setTraceMethod(String traceMethod)16131         HandlerParams setTraceMethod(String traceMethod) {
16132             this.traceMethod = traceMethod;
16133             return this;
16134         }
16135 
setTraceCookie(int traceCookie)16136         HandlerParams setTraceCookie(int traceCookie) {
16137             this.traceCookie = traceCookie;
16138             return this;
16139         }
16140 
startCopy()16141         final boolean startCopy() {
16142             boolean res;
16143             try {
16144                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
16145 
16146                 if (++mRetries > MAX_RETRIES) {
16147                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
16148                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
16149                     handleServiceError();
16150                     return false;
16151                 } else {
16152                     handleStartCopy();
16153                     res = true;
16154                 }
16155             } catch (RemoteException e) {
16156                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
16157                 mHandler.sendEmptyMessage(MCS_RECONNECT);
16158                 res = false;
16159             }
16160             handleReturnCode();
16161             return res;
16162         }
16163 
serviceError()16164         final void serviceError() {
16165             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
16166             handleServiceError();
16167             handleReturnCode();
16168         }
16169 
handleStartCopy()16170         abstract void handleStartCopy() throws RemoteException;
handleServiceError()16171         abstract void handleServiceError();
handleReturnCode()16172         abstract void handleReturnCode();
16173     }
16174 
clearDirectory(IMediaContainerService mcs, File[] paths)16175     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
16176         for (File path : paths) {
16177             try {
16178                 mcs.clearDirectory(path.getAbsolutePath());
16179             } catch (RemoteException e) {
16180             }
16181         }
16182     }
16183 
16184     static class OriginInfo {
16185         /**
16186          * Location where install is coming from, before it has been
16187          * copied/renamed into place. This could be a single monolithic APK
16188          * file, or a cluster directory. This location may be untrusted.
16189          */
16190         final File file;
16191         final String cid;
16192 
16193         /**
16194          * Flag indicating that {@link #file} or {@link #cid} has already been
16195          * staged, meaning downstream users don't need to defensively copy the
16196          * contents.
16197          */
16198         final boolean staged;
16199 
16200         /**
16201          * Flag indicating that {@link #file} or {@link #cid} is an already
16202          * installed app that is being moved.
16203          */
16204         final boolean existing;
16205 
16206         final String resolvedPath;
16207         final File resolvedFile;
16208 
fromNothing()16209         static OriginInfo fromNothing() {
16210             return new OriginInfo(null, null, false, false);
16211         }
16212 
fromUntrustedFile(File file)16213         static OriginInfo fromUntrustedFile(File file) {
16214             return new OriginInfo(file, null, false, false);
16215         }
16216 
fromExistingFile(File file)16217         static OriginInfo fromExistingFile(File file) {
16218             return new OriginInfo(file, null, false, true);
16219         }
16220 
fromStagedFile(File file)16221         static OriginInfo fromStagedFile(File file) {
16222             return new OriginInfo(file, null, true, false);
16223         }
16224 
fromStagedContainer(String cid)16225         static OriginInfo fromStagedContainer(String cid) {
16226             return new OriginInfo(null, cid, true, false);
16227         }
16228 
OriginInfo(File file, String cid, boolean staged, boolean existing)16229         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
16230             this.file = file;
16231             this.cid = cid;
16232             this.staged = staged;
16233             this.existing = existing;
16234 
16235             if (cid != null) {
16236                 resolvedPath = PackageHelper.getSdDir(cid);
16237                 resolvedFile = new File(resolvedPath);
16238             } else if (file != null) {
16239                 resolvedPath = file.getAbsolutePath();
16240                 resolvedFile = file;
16241             } else {
16242                 resolvedPath = null;
16243                 resolvedFile = null;
16244             }
16245         }
16246     }
16247 
16248     static class MoveInfo {
16249         final int moveId;
16250         final String fromUuid;
16251         final String toUuid;
16252         final String packageName;
16253         final String dataAppName;
16254         final int appId;
16255         final String seinfo;
16256         final int targetSdkVersion;
16257 
MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, String dataAppName, int appId, String seinfo, int targetSdkVersion)16258         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
16259                 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
16260             this.moveId = moveId;
16261             this.fromUuid = fromUuid;
16262             this.toUuid = toUuid;
16263             this.packageName = packageName;
16264             this.dataAppName = dataAppName;
16265             this.appId = appId;
16266             this.seinfo = seinfo;
16267             this.targetSdkVersion = targetSdkVersion;
16268         }
16269     }
16270 
16271     static class VerificationInfo {
16272         /** A constant used to indicate that a uid value is not present. */
16273         public static final int NO_UID = -1;
16274 
16275         /** URI referencing where the package was downloaded from. */
16276         final Uri originatingUri;
16277 
16278         /** HTTP referrer URI associated with the originatingURI. */
16279         final Uri referrer;
16280 
16281         /** UID of the application that the install request originated from. */
16282         final int originatingUid;
16283 
16284         /** UID of application requesting the install */
16285         final int installerUid;
16286 
VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid)16287         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
16288             this.originatingUri = originatingUri;
16289             this.referrer = referrer;
16290             this.originatingUid = originatingUid;
16291             this.installerUid = installerUid;
16292         }
16293     }
16294 
16295     class InstallParams extends HandlerParams {
16296         final OriginInfo origin;
16297         final MoveInfo move;
16298         final IPackageInstallObserver2 observer;
16299         int installFlags;
16300         final String installerPackageName;
16301         final String volumeUuid;
16302         private InstallArgs mArgs;
16303         private int mRet;
16304         final String packageAbiOverride;
16305         final String[] grantedRuntimePermissions;
16306         final VerificationInfo verificationInfo;
16307         final Certificate[][] certificates;
16308         final int installReason;
16309 
InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, String[] grantedPermissions, Certificate[][] certificates, int installReason)16310         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16311                 int installFlags, String installerPackageName, String volumeUuid,
16312                 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
16313                 String[] grantedPermissions, Certificate[][] certificates, int installReason) {
16314             super(user);
16315             this.origin = origin;
16316             this.move = move;
16317             this.observer = observer;
16318             this.installFlags = installFlags;
16319             this.installerPackageName = installerPackageName;
16320             this.volumeUuid = volumeUuid;
16321             this.verificationInfo = verificationInfo;
16322             this.packageAbiOverride = packageAbiOverride;
16323             this.grantedRuntimePermissions = grantedPermissions;
16324             this.certificates = certificates;
16325             this.installReason = installReason;
16326         }
16327 
16328         @Override
toString()16329         public String toString() {
16330             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
16331                     + " file=" + origin.file + " cid=" + origin.cid + "}";
16332         }
16333 
installLocationPolicy(PackageInfoLite pkgLite)16334         private int installLocationPolicy(PackageInfoLite pkgLite) {
16335             String packageName = pkgLite.packageName;
16336             int installLocation = pkgLite.installLocation;
16337             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16338             // reader
16339             synchronized (mPackages) {
16340                 // Currently installed package which the new package is attempting to replace or
16341                 // null if no such package is installed.
16342                 PackageParser.Package installedPkg = mPackages.get(packageName);
16343                 // Package which currently owns the data which the new package will own if installed.
16344                 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
16345                 // will be null whereas dataOwnerPkg will contain information about the package
16346                 // which was uninstalled while keeping its data.
16347                 PackageParser.Package dataOwnerPkg = installedPkg;
16348                 if (dataOwnerPkg  == null) {
16349                     PackageSetting ps = mSettings.mPackages.get(packageName);
16350                     if (ps != null) {
16351                         dataOwnerPkg = ps.pkg;
16352                     }
16353                 }
16354 
16355                 if (dataOwnerPkg != null) {
16356                     // If installed, the package will get access to data left on the device by its
16357                     // predecessor. As a security measure, this is permited only if this is not a
16358                     // version downgrade or if the predecessor package is marked as debuggable and
16359                     // a downgrade is explicitly requested.
16360                     //
16361                     // On debuggable platform builds, downgrades are permitted even for
16362                     // non-debuggable packages to make testing easier. Debuggable platform builds do
16363                     // not offer security guarantees and thus it's OK to disable some security
16364                     // mechanisms to make debugging/testing easier on those builds. However, even on
16365                     // debuggable builds downgrades of packages are permitted only if requested via
16366                     // installFlags. This is because we aim to keep the behavior of debuggable
16367                     // platform builds as close as possible to the behavior of non-debuggable
16368                     // platform builds.
16369                     final boolean downgradeRequested =
16370                             (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
16371                     final boolean packageDebuggable =
16372                                 (dataOwnerPkg.applicationInfo.flags
16373                                         & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
16374                     final boolean downgradePermitted =
16375                             (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
16376                     if (!downgradePermitted) {
16377                         try {
16378                             checkDowngrade(dataOwnerPkg, pkgLite);
16379                         } catch (PackageManagerException e) {
16380                             Slog.w(TAG, "Downgrade detected: " + e.getMessage());
16381                             return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
16382                         }
16383                     }
16384                 }
16385 
16386                 if (installedPkg != null) {
16387                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16388                         // Check for updated system application.
16389                         if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16390                             if (onSd) {
16391                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
16392                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
16393                             }
16394                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16395                         } else {
16396                             if (onSd) {
16397                                 // Install flag overrides everything.
16398                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16399                             }
16400                             // If current upgrade specifies particular preference
16401                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
16402                                 // Application explicitly specified internal.
16403                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16404                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
16405                                 // App explictly prefers external. Let policy decide
16406                             } else {
16407                                 // Prefer previous location
16408                                 if (isExternal(installedPkg)) {
16409                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16410                                 }
16411                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16412                             }
16413                         }
16414                     } else {
16415                         // Invalid install. Return error code
16416                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
16417                     }
16418                 }
16419             }
16420             // All the special cases have been taken care of.
16421             // Return result based on recommended install location.
16422             if (onSd) {
16423                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16424             }
16425             return pkgLite.recommendedInstallLocation;
16426         }
16427 
16428         /*
16429          * Invoke remote method to get package information and install
16430          * location values. Override install location based on default
16431          * policy if needed and then create install arguments based
16432          * on the install location.
16433          */
handleStartCopy()16434         public void handleStartCopy() throws RemoteException {
16435             int ret = PackageManager.INSTALL_SUCCEEDED;
16436 
16437             // If we're already staged, we've firmly committed to an install location
16438             if (origin.staged) {
16439                 if (origin.file != null) {
16440                     installFlags |= PackageManager.INSTALL_INTERNAL;
16441                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16442                 } else if (origin.cid != null) {
16443                     installFlags |= PackageManager.INSTALL_EXTERNAL;
16444                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
16445                 } else {
16446                     throw new IllegalStateException("Invalid stage location");
16447                 }
16448             }
16449 
16450             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16451             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
16452             final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16453             PackageInfoLite pkgLite = null;
16454 
16455             if (onInt && onSd) {
16456                 // Check if both bits are set.
16457                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
16458                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16459             } else if (onSd && ephemeral) {
16460                 Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
16461                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16462             } else {
16463                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
16464                         packageAbiOverride);
16465 
16466                 if (DEBUG_EPHEMERAL && ephemeral) {
16467                     Slog.v(TAG, "pkgLite for install: " + pkgLite);
16468                 }
16469 
16470                 /*
16471                  * If we have too little free space, try to free cache
16472                  * before giving up.
16473                  */
16474                 if (!origin.staged && pkgLite.recommendedInstallLocation
16475                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16476                     // TODO: focus freeing disk space on the target device
16477                     final StorageManager storage = StorageManager.from(mContext);
16478                     final long lowThreshold = storage.getStorageLowBytes(
16479                             Environment.getDataDirectory());
16480 
16481                     final long sizeBytes = mContainerService.calculateInstalledSize(
16482                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
16483 
16484                     try {
16485                         mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
16486                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
16487                                 installFlags, packageAbiOverride);
16488                     } catch (InstallerException e) {
16489                         Slog.w(TAG, "Failed to free cache", e);
16490                     }
16491 
16492                     /*
16493                      * The cache free must have deleted the file we
16494                      * downloaded to install.
16495                      *
16496                      * TODO: fix the "freeCache" call to not delete
16497                      *       the file we care about.
16498                      */
16499                     if (pkgLite.recommendedInstallLocation
16500                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16501                         pkgLite.recommendedInstallLocation
16502                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
16503                     }
16504                 }
16505             }
16506 
16507             if (ret == PackageManager.INSTALL_SUCCEEDED) {
16508                 int loc = pkgLite.recommendedInstallLocation;
16509                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
16510                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16511                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
16512                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
16513                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16514                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16515                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
16516                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
16517                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16518                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
16519                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
16520                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
16521                 } else {
16522                     // Override with defaults if needed.
16523                     loc = installLocationPolicy(pkgLite);
16524                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
16525                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
16526                     } else if (!onSd && !onInt) {
16527                         // Override install location with flags
16528                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
16529                             // Set the flag to install on external media.
16530                             installFlags |= PackageManager.INSTALL_EXTERNAL;
16531                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
16532                         } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
16533                             if (DEBUG_EPHEMERAL) {
16534                                 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
16535                             }
16536                             installFlags |= PackageManager.INSTALL_INSTANT_APP;
16537                             installFlags &= ~(PackageManager.INSTALL_EXTERNAL
16538                                     |PackageManager.INSTALL_INTERNAL);
16539                         } else {
16540                             // Make sure the flag for installing on external
16541                             // media is unset
16542                             installFlags |= PackageManager.INSTALL_INTERNAL;
16543                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16544                         }
16545                     }
16546                 }
16547             }
16548 
16549             final InstallArgs args = createInstallArgs(this);
16550             mArgs = args;
16551 
16552             if (ret == PackageManager.INSTALL_SUCCEEDED) {
16553                 // TODO: http://b/22976637
16554                 // Apps installed for "all" users use the device owner to verify the app
16555                 UserHandle verifierUser = getUser();
16556                 if (verifierUser == UserHandle.ALL) {
16557                     verifierUser = UserHandle.SYSTEM;
16558                 }
16559 
16560                 /*
16561                  * Determine if we have any installed package verifiers. If we
16562                  * do, then we'll defer to them to verify the packages.
16563                  */
16564                 final int requiredUid = mRequiredVerifierPackage == null ? -1
16565                         : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
16566                                 verifierUser.getIdentifier());
16567                 final int installerUid =
16568                         verificationInfo == null ? -1 : verificationInfo.installerUid;
16569                 if (!origin.existing && requiredUid != -1
16570                         && isVerificationEnabled(
16571                                 verifierUser.getIdentifier(), installFlags, installerUid)) {
16572                     final Intent verification = new Intent(
16573                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
16574                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16575                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
16576                             PACKAGE_MIME_TYPE);
16577                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16578 
16579                     // Query all live verifiers based on current user state
16580                     final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
16581                             PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
16582                             false /*allowDynamicSplits*/);
16583 
16584                     if (DEBUG_VERIFY) {
16585                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
16586                                 + verification.toString() + " with " + pkgLite.verifiers.length
16587                                 + " optional verifiers");
16588                     }
16589 
16590                     final int verificationId = mPendingVerificationToken++;
16591 
16592                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16593 
16594                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
16595                             installerPackageName);
16596 
16597                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
16598                             installFlags);
16599 
16600                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
16601                             pkgLite.packageName);
16602 
16603                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
16604                             pkgLite.versionCode);
16605 
16606                     if (verificationInfo != null) {
16607                         if (verificationInfo.originatingUri != null) {
16608                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
16609                                     verificationInfo.originatingUri);
16610                         }
16611                         if (verificationInfo.referrer != null) {
16612                             verification.putExtra(Intent.EXTRA_REFERRER,
16613                                     verificationInfo.referrer);
16614                         }
16615                         if (verificationInfo.originatingUid >= 0) {
16616                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
16617                                     verificationInfo.originatingUid);
16618                         }
16619                         if (verificationInfo.installerUid >= 0) {
16620                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
16621                                     verificationInfo.installerUid);
16622                         }
16623                     }
16624 
16625                     final PackageVerificationState verificationState = new PackageVerificationState(
16626                             requiredUid, args);
16627 
16628                     mPendingVerification.append(verificationId, verificationState);
16629 
16630                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
16631                             receivers, verificationState);
16632 
16633                     DeviceIdleController.LocalService idleController = getDeviceIdleController();
16634                     final long idleDuration = getVerificationTimeout();
16635 
16636                     /*
16637                      * If any sufficient verifiers were listed in the package
16638                      * manifest, attempt to ask them.
16639                      */
16640                     if (sufficientVerifiers != null) {
16641                         final int N = sufficientVerifiers.size();
16642                         if (N == 0) {
16643                             Slog.i(TAG, "Additional verifiers required, but none installed.");
16644                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
16645                         } else {
16646                             for (int i = 0; i < N; i++) {
16647                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
16648                                 idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16649                                         verifierComponent.getPackageName(), idleDuration,
16650                                         verifierUser.getIdentifier(), false, "package verifier");
16651 
16652                                 final Intent sufficientIntent = new Intent(verification);
16653                                 sufficientIntent.setComponent(verifierComponent);
16654                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
16655                             }
16656                         }
16657                     }
16658 
16659                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
16660                             mRequiredVerifierPackage, receivers);
16661                     if (ret == PackageManager.INSTALL_SUCCEEDED
16662                             && mRequiredVerifierPackage != null) {
16663                         Trace.asyncTraceBegin(
16664                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
16665                         /*
16666                          * Send the intent to the required verification agent,
16667                          * but only start the verification timeout after the
16668                          * target BroadcastReceivers have run.
16669                          */
16670                         verification.setComponent(requiredVerifierComponent);
16671                         idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16672                                 mRequiredVerifierPackage, idleDuration,
16673                                 verifierUser.getIdentifier(), false, "package verifier");
16674                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
16675                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16676                                 new BroadcastReceiver() {
16677                                     @Override
16678                                     public void onReceive(Context context, Intent intent) {
16679                                         final Message msg = mHandler
16680                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
16681                                         msg.arg1 = verificationId;
16682                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
16683                                     }
16684                                 }, null, 0, null, null);
16685 
16686                         /*
16687                          * We don't want the copy to proceed until verification
16688                          * succeeds, so null out this field.
16689                          */
16690                         mArgs = null;
16691                     }
16692                 } else {
16693                     /*
16694                      * No package verification is enabled, so immediately start
16695                      * the remote call to initiate copy using temporary file.
16696                      */
16697                     ret = args.copyApk(mContainerService, true);
16698                 }
16699             }
16700 
16701             mRet = ret;
16702         }
16703 
16704         @Override
handleReturnCode()16705         void handleReturnCode() {
16706             // If mArgs is null, then MCS couldn't be reached. When it
16707             // reconnects, it will try again to install. At that point, this
16708             // will succeed.
16709             if (mArgs != null) {
16710                 processPendingInstall(mArgs, mRet);
16711             }
16712         }
16713 
16714         @Override
handleServiceError()16715         void handleServiceError() {
16716             mArgs = createInstallArgs(this);
16717             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16718         }
16719 
isForwardLocked()16720         public boolean isForwardLocked() {
16721             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16722         }
16723     }
16724 
16725     /**
16726      * Used during creation of InstallArgs
16727      *
16728      * @param installFlags package installation flags
16729      * @return true if should be installed on external storage
16730      */
installOnExternalAsec(int installFlags)16731     private static boolean installOnExternalAsec(int installFlags) {
16732         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
16733             return false;
16734         }
16735         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
16736             return true;
16737         }
16738         return false;
16739     }
16740 
16741     /**
16742      * Used during creation of InstallArgs
16743      *
16744      * @param installFlags package installation flags
16745      * @return true if should be installed as forward locked
16746      */
installForwardLocked(int installFlags)16747     private static boolean installForwardLocked(int installFlags) {
16748         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16749     }
16750 
createInstallArgs(InstallParams params)16751     private InstallArgs createInstallArgs(InstallParams params) {
16752         if (params.move != null) {
16753             return new MoveInstallArgs(params);
16754         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
16755             return new AsecInstallArgs(params);
16756         } else {
16757             return new FileInstallArgs(params);
16758         }
16759     }
16760 
16761     /**
16762      * Create args that describe an existing installed package. Typically used
16763      * when cleaning up old installs, or used as a move source.
16764      */
createInstallArgsForExisting(int installFlags, String codePath, String resourcePath, String[] instructionSets)16765     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16766             String resourcePath, String[] instructionSets) {
16767         final boolean isInAsec;
16768         if (installOnExternalAsec(installFlags)) {
16769             /* Apps on SD card are always in ASEC containers. */
16770             isInAsec = true;
16771         } else if (installForwardLocked(installFlags)
16772                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
16773             /*
16774              * Forward-locked apps are only in ASEC containers if they're the
16775              * new style
16776              */
16777             isInAsec = true;
16778         } else {
16779             isInAsec = false;
16780         }
16781 
16782         if (isInAsec) {
16783             return new AsecInstallArgs(codePath, instructionSets,
16784                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
16785         } else {
16786             return new FileInstallArgs(codePath, resourcePath, instructionSets);
16787         }
16788     }
16789 
16790     static abstract class InstallArgs {
16791         /** @see InstallParams#origin */
16792         final OriginInfo origin;
16793         /** @see InstallParams#move */
16794         final MoveInfo move;
16795 
16796         final IPackageInstallObserver2 observer;
16797         // Always refers to PackageManager flags only
16798         final int installFlags;
16799         final String installerPackageName;
16800         final String volumeUuid;
16801         final UserHandle user;
16802         final String abiOverride;
16803         final String[] installGrantPermissions;
16804         /** If non-null, drop an async trace when the install completes */
16805         final String traceMethod;
16806         final int traceCookie;
16807         final Certificate[][] certificates;
16808         final int installReason;
16809 
16810         // The list of instruction sets supported by this app. This is currently
16811         // only used during the rmdex() phase to clean up resources. We can get rid of this
16812         // if we move dex files under the common app path.
16813         /* nullable */ String[] instructionSets;
16814 
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, int installReason)16815         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16816                 int installFlags, String installerPackageName, String volumeUuid,
16817                 UserHandle user, String[] instructionSets,
16818                 String abiOverride, String[] installGrantPermissions,
16819                 String traceMethod, int traceCookie, Certificate[][] certificates,
16820                 int installReason) {
16821             this.origin = origin;
16822             this.move = move;
16823             this.installFlags = installFlags;
16824             this.observer = observer;
16825             this.installerPackageName = installerPackageName;
16826             this.volumeUuid = volumeUuid;
16827             this.user = user;
16828             this.instructionSets = instructionSets;
16829             this.abiOverride = abiOverride;
16830             this.installGrantPermissions = installGrantPermissions;
16831             this.traceMethod = traceMethod;
16832             this.traceCookie = traceCookie;
16833             this.certificates = certificates;
16834             this.installReason = installReason;
16835         }
16836 
copyApk(IMediaContainerService imcs, boolean temp)16837         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
doPreInstall(int status)16838         abstract int doPreInstall(int status);
16839 
16840         /**
16841          * Rename package into final resting place. All paths on the given
16842          * scanned package should be updated to reflect the rename.
16843          */
doRename(int status, PackageParser.Package pkg, String oldCodePath)16844         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
doPostInstall(int status, int uid)16845         abstract int doPostInstall(int status, int uid);
16846 
16847         /** @see PackageSettingBase#codePathString */
getCodePath()16848         abstract String getCodePath();
16849         /** @see PackageSettingBase#resourcePathString */
getResourcePath()16850         abstract String getResourcePath();
16851 
16852         // Need installer lock especially for dex file removal.
cleanUpResourcesLI()16853         abstract void cleanUpResourcesLI();
doPostDeleteLI(boolean delete)16854         abstract boolean doPostDeleteLI(boolean delete);
16855 
16856         /**
16857          * Called before the source arguments are copied. This is used mostly
16858          * for MoveParams when it needs to read the source file to put it in the
16859          * destination.
16860          */
doPreCopy()16861         int doPreCopy() {
16862             return PackageManager.INSTALL_SUCCEEDED;
16863         }
16864 
16865         /**
16866          * Called after the source arguments are copied. This is used mostly for
16867          * MoveParams when it needs to read the source file to put it in the
16868          * destination.
16869          */
doPostCopy(int uid)16870         int doPostCopy(int uid) {
16871             return PackageManager.INSTALL_SUCCEEDED;
16872         }
16873 
isFwdLocked()16874         protected boolean isFwdLocked() {
16875             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16876         }
16877 
isExternalAsec()16878         protected boolean isExternalAsec() {
16879             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16880         }
16881 
isEphemeral()16882         protected boolean isEphemeral() {
16883             return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16884         }
16885 
getUser()16886         UserHandle getUser() {
16887             return user;
16888         }
16889     }
16890 
removeDexFiles(List<String> allCodePaths, String[] instructionSets)16891     void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16892         if (!allCodePaths.isEmpty()) {
16893             if (instructionSets == null) {
16894                 throw new IllegalStateException("instructionSet == null");
16895             }
16896             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16897             for (String codePath : allCodePaths) {
16898                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16899                     try {
16900                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
16901                     } catch (InstallerException ignored) {
16902                     }
16903                 }
16904             }
16905         }
16906     }
16907 
16908     /**
16909      * Logic to handle installation of non-ASEC applications, including copying
16910      * and renaming logic.
16911      */
16912     class FileInstallArgs extends InstallArgs {
16913         private File codeFile;
16914         private File resourceFile;
16915 
16916         // Example topology:
16917         // /data/app/com.example/base.apk
16918         // /data/app/com.example/split_foo.apk
16919         // /data/app/com.example/lib/arm/libfoo.so
16920         // /data/app/com.example/lib/arm64/libfoo.so
16921         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16922 
16923         /** New install */
FileInstallArgs(InstallParams params)16924         FileInstallArgs(InstallParams params) {
16925             super(params.origin, params.move, params.observer, params.installFlags,
16926                     params.installerPackageName, params.volumeUuid,
16927                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16928                     params.grantedRuntimePermissions,
16929                     params.traceMethod, params.traceCookie, params.certificates,
16930                     params.installReason);
16931             if (isFwdLocked()) {
16932                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
16933             }
16934         }
16935 
16936         /** Existing install */
FileInstallArgs(String codePath, String resourcePath, String[] instructionSets)16937         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16938             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16939                     null, null, null, 0, null /*certificates*/,
16940                     PackageManager.INSTALL_REASON_UNKNOWN);
16941             this.codeFile = (codePath != null) ? new File(codePath) : null;
16942             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16943         }
16944 
copyApk(IMediaContainerService imcs, boolean temp)16945         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16946             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16947             try {
16948                 return doCopyApk(imcs, temp);
16949             } finally {
16950                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16951             }
16952         }
16953 
doCopyApk(IMediaContainerService imcs, boolean temp)16954         private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16955             if (origin.staged) {
16956                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16957                 codeFile = origin.file;
16958                 resourceFile = origin.file;
16959                 return PackageManager.INSTALL_SUCCEEDED;
16960             }
16961 
16962             try {
16963                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16964                 final File tempDir =
16965                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16966                 codeFile = tempDir;
16967                 resourceFile = tempDir;
16968             } catch (IOException e) {
16969                 Slog.w(TAG, "Failed to create copy file: " + e);
16970                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16971             }
16972 
16973             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16974                 @Override
16975                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16976                     if (!FileUtils.isValidExtFilename(name)) {
16977                         throw new IllegalArgumentException("Invalid filename: " + name);
16978                     }
16979                     try {
16980                         final File file = new File(codeFile, name);
16981                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16982                                 O_RDWR | O_CREAT, 0644);
16983                         Os.chmod(file.getAbsolutePath(), 0644);
16984                         return new ParcelFileDescriptor(fd);
16985                     } catch (ErrnoException e) {
16986                         throw new RemoteException("Failed to open: " + e.getMessage());
16987                     }
16988                 }
16989             };
16990 
16991             int ret = PackageManager.INSTALL_SUCCEEDED;
16992             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16993             if (ret != PackageManager.INSTALL_SUCCEEDED) {
16994                 Slog.e(TAG, "Failed to copy package");
16995                 return ret;
16996             }
16997 
16998             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16999             NativeLibraryHelper.Handle handle = null;
17000             try {
17001                 handle = NativeLibraryHelper.Handle.create(codeFile);
17002                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
17003                         abiOverride);
17004             } catch (IOException e) {
17005                 Slog.e(TAG, "Copying native libraries failed", e);
17006                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
17007             } finally {
17008                 IoUtils.closeQuietly(handle);
17009             }
17010 
17011             return ret;
17012         }
17013 
doPreInstall(int status)17014         int doPreInstall(int status) {
17015             if (status != PackageManager.INSTALL_SUCCEEDED) {
17016                 cleanUp();
17017             }
17018             return status;
17019         }
17020 
doRename(int status, PackageParser.Package pkg, String oldCodePath)17021         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17022             if (status != PackageManager.INSTALL_SUCCEEDED) {
17023                 cleanUp();
17024                 return false;
17025             }
17026 
17027             final File targetDir = codeFile.getParentFile();
17028             final File beforeCodeFile = codeFile;
17029             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
17030 
17031             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
17032             try {
17033                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
17034             } catch (ErrnoException e) {
17035                 Slog.w(TAG, "Failed to rename", e);
17036                 return false;
17037             }
17038 
17039             if (!SELinux.restoreconRecursive(afterCodeFile)) {
17040                 Slog.w(TAG, "Failed to restorecon");
17041                 return false;
17042             }
17043 
17044             // Reflect the rename internally
17045             codeFile = afterCodeFile;
17046             resourceFile = afterCodeFile;
17047 
17048             // Reflect the rename in scanned details
17049             pkg.setCodePath(afterCodeFile.getAbsolutePath());
17050             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
17051                     afterCodeFile, pkg.baseCodePath));
17052             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
17053                     afterCodeFile, pkg.splitCodePaths));
17054 
17055             // Reflect the rename in app info
17056             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17057             pkg.setApplicationInfoCodePath(pkg.codePath);
17058             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17059             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17060             pkg.setApplicationInfoResourcePath(pkg.codePath);
17061             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17062             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17063 
17064             return true;
17065         }
17066 
doPostInstall(int status, int uid)17067         int doPostInstall(int status, int uid) {
17068             if (status != PackageManager.INSTALL_SUCCEEDED) {
17069                 cleanUp();
17070             }
17071             return status;
17072         }
17073 
17074         @Override
getCodePath()17075         String getCodePath() {
17076             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17077         }
17078 
17079         @Override
getResourcePath()17080         String getResourcePath() {
17081             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17082         }
17083 
cleanUp()17084         private boolean cleanUp() {
17085             if (codeFile == null || !codeFile.exists()) {
17086                 return false;
17087             }
17088 
17089             removeCodePathLI(codeFile);
17090 
17091             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
17092                 resourceFile.delete();
17093             }
17094 
17095             return true;
17096         }
17097 
cleanUpResourcesLI()17098         void cleanUpResourcesLI() {
17099             // Try enumerating all code paths before deleting
17100             List<String> allCodePaths = Collections.EMPTY_LIST;
17101             if (codeFile != null && codeFile.exists()) {
17102                 try {
17103                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
17104                     allCodePaths = pkg.getAllCodePaths();
17105                 } catch (PackageParserException e) {
17106                     // Ignored; we tried our best
17107                 }
17108             }
17109 
17110             cleanUp();
17111             removeDexFiles(allCodePaths, instructionSets);
17112         }
17113 
doPostDeleteLI(boolean delete)17114         boolean doPostDeleteLI(boolean delete) {
17115             // XXX err, shouldn't we respect the delete flag?
17116             cleanUpResourcesLI();
17117             return true;
17118         }
17119     }
17120 
isAsecExternal(String cid)17121     private boolean isAsecExternal(String cid) {
17122         final String asecPath = PackageHelper.getSdFilesystem(cid);
17123         return !asecPath.startsWith(mAsecInternalPath);
17124     }
17125 
maybeThrowExceptionForMultiArchCopy(String message, int copyRet)17126     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
17127             PackageManagerException {
17128         if (copyRet < 0) {
17129             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
17130                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
17131                 throw new PackageManagerException(copyRet, message);
17132             }
17133         }
17134     }
17135 
17136     /**
17137      * Extract the StorageManagerService "container ID" from the full code path of an
17138      * .apk.
17139      */
cidFromCodePath(String fullCodePath)17140     static String cidFromCodePath(String fullCodePath) {
17141         int eidx = fullCodePath.lastIndexOf("/");
17142         String subStr1 = fullCodePath.substring(0, eidx);
17143         int sidx = subStr1.lastIndexOf("/");
17144         return subStr1.substring(sidx+1, eidx);
17145     }
17146 
17147     /**
17148      * Logic to handle installation of ASEC applications, including copying and
17149      * renaming logic.
17150      */
17151     class AsecInstallArgs extends InstallArgs {
17152         static final String RES_FILE_NAME = "pkg.apk";
17153         static final String PUBLIC_RES_FILE_NAME = "res.zip";
17154 
17155         String cid;
17156         String packagePath;
17157         String resourcePath;
17158 
17159         /** New install */
AsecInstallArgs(InstallParams params)17160         AsecInstallArgs(InstallParams params) {
17161             super(params.origin, params.move, params.observer, params.installFlags,
17162                     params.installerPackageName, params.volumeUuid,
17163                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17164                     params.grantedRuntimePermissions,
17165                     params.traceMethod, params.traceCookie, params.certificates,
17166                     params.installReason);
17167         }
17168 
17169         /** Existing install */
AsecInstallArgs(String fullCodePath, String[] instructionSets, boolean isExternal, boolean isForwardLocked)17170         AsecInstallArgs(String fullCodePath, String[] instructionSets,
17171                         boolean isExternal, boolean isForwardLocked) {
17172             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
17173                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
17174                     instructionSets, null, null, null, 0, null /*certificates*/,
17175                     PackageManager.INSTALL_REASON_UNKNOWN);
17176             // Hackily pretend we're still looking at a full code path
17177             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
17178                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
17179             }
17180 
17181             // Extract cid from fullCodePath
17182             int eidx = fullCodePath.lastIndexOf("/");
17183             String subStr1 = fullCodePath.substring(0, eidx);
17184             int sidx = subStr1.lastIndexOf("/");
17185             cid = subStr1.substring(sidx+1, eidx);
17186             setMountPath(subStr1);
17187         }
17188 
AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked)17189         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
17190             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
17191                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
17192                     instructionSets, null, null, null, 0, null /*certificates*/,
17193                     PackageManager.INSTALL_REASON_UNKNOWN);
17194             this.cid = cid;
17195             setMountPath(PackageHelper.getSdDir(cid));
17196         }
17197 
createCopyFile()17198         void createCopyFile() {
17199             cid = mInstallerService.allocateExternalStageCidLegacy();
17200         }
17201 
copyApk(IMediaContainerService imcs, boolean temp)17202         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
17203             if (origin.staged && origin.cid != null) {
17204                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
17205                 cid = origin.cid;
17206                 setMountPath(PackageHelper.getSdDir(cid));
17207                 return PackageManager.INSTALL_SUCCEEDED;
17208             }
17209 
17210             if (temp) {
17211                 createCopyFile();
17212             } else {
17213                 /*
17214                  * Pre-emptively destroy the container since it's destroyed if
17215                  * copying fails due to it existing anyway.
17216                  */
17217                 PackageHelper.destroySdDir(cid);
17218             }
17219 
17220             final String newMountPath = imcs.copyPackageToContainer(
17221                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
17222                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
17223 
17224             if (newMountPath != null) {
17225                 setMountPath(newMountPath);
17226                 return PackageManager.INSTALL_SUCCEEDED;
17227             } else {
17228                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17229             }
17230         }
17231 
17232         @Override
getCodePath()17233         String getCodePath() {
17234             return packagePath;
17235         }
17236 
17237         @Override
getResourcePath()17238         String getResourcePath() {
17239             return resourcePath;
17240         }
17241 
doPreInstall(int status)17242         int doPreInstall(int status) {
17243             if (status != PackageManager.INSTALL_SUCCEEDED) {
17244                 // Destroy container
17245                 PackageHelper.destroySdDir(cid);
17246             } else {
17247                 boolean mounted = PackageHelper.isContainerMounted(cid);
17248                 if (!mounted) {
17249                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
17250                             Process.SYSTEM_UID);
17251                     if (newMountPath != null) {
17252                         setMountPath(newMountPath);
17253                     } else {
17254                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17255                     }
17256                 }
17257             }
17258             return status;
17259         }
17260 
doRename(int status, PackageParser.Package pkg, String oldCodePath)17261         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17262             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
17263             String newMountPath = null;
17264             if (PackageHelper.isContainerMounted(cid)) {
17265                 // Unmount the container
17266                 if (!PackageHelper.unMountSdDir(cid)) {
17267                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
17268                     return false;
17269                 }
17270             }
17271             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17272                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
17273                         " which might be stale. Will try to clean up.");
17274                 // Clean up the stale container and proceed to recreate.
17275                 if (!PackageHelper.destroySdDir(newCacheId)) {
17276                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
17277                     return false;
17278                 }
17279                 // Successfully cleaned up stale container. Try to rename again.
17280                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17281                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
17282                             + " inspite of cleaning it up.");
17283                     return false;
17284                 }
17285             }
17286             if (!PackageHelper.isContainerMounted(newCacheId)) {
17287                 Slog.w(TAG, "Mounting container " + newCacheId);
17288                 newMountPath = PackageHelper.mountSdDir(newCacheId,
17289                         getEncryptKey(), Process.SYSTEM_UID);
17290             } else {
17291                 newMountPath = PackageHelper.getSdDir(newCacheId);
17292             }
17293             if (newMountPath == null) {
17294                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
17295                 return false;
17296             }
17297             Log.i(TAG, "Succesfully renamed " + cid +
17298                     " to " + newCacheId +
17299                     " at new path: " + newMountPath);
17300             cid = newCacheId;
17301 
17302             final File beforeCodeFile = new File(packagePath);
17303             setMountPath(newMountPath);
17304             final File afterCodeFile = new File(packagePath);
17305 
17306             // Reflect the rename in scanned details
17307             pkg.setCodePath(afterCodeFile.getAbsolutePath());
17308             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
17309                     afterCodeFile, pkg.baseCodePath));
17310             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
17311                     afterCodeFile, pkg.splitCodePaths));
17312 
17313             // Reflect the rename in app info
17314             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17315             pkg.setApplicationInfoCodePath(pkg.codePath);
17316             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17317             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17318             pkg.setApplicationInfoResourcePath(pkg.codePath);
17319             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17320             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17321 
17322             return true;
17323         }
17324 
setMountPath(String mountPath)17325         private void setMountPath(String mountPath) {
17326             final File mountFile = new File(mountPath);
17327 
17328             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
17329             if (monolithicFile.exists()) {
17330                 packagePath = monolithicFile.getAbsolutePath();
17331                 if (isFwdLocked()) {
17332                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
17333                 } else {
17334                     resourcePath = packagePath;
17335                 }
17336             } else {
17337                 packagePath = mountFile.getAbsolutePath();
17338                 resourcePath = packagePath;
17339             }
17340         }
17341 
doPostInstall(int status, int uid)17342         int doPostInstall(int status, int uid) {
17343             if (status != PackageManager.INSTALL_SUCCEEDED) {
17344                 cleanUp();
17345             } else {
17346                 final int groupOwner;
17347                 final String protectedFile;
17348                 if (isFwdLocked()) {
17349                     groupOwner = UserHandle.getSharedAppGid(uid);
17350                     protectedFile = RES_FILE_NAME;
17351                 } else {
17352                     groupOwner = -1;
17353                     protectedFile = null;
17354                 }
17355 
17356                 if (uid < Process.FIRST_APPLICATION_UID
17357                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
17358                     Slog.e(TAG, "Failed to finalize " + cid);
17359                     PackageHelper.destroySdDir(cid);
17360                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17361                 }
17362 
17363                 boolean mounted = PackageHelper.isContainerMounted(cid);
17364                 if (!mounted) {
17365                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
17366                 }
17367             }
17368             return status;
17369         }
17370 
cleanUp()17371         private void cleanUp() {
17372             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
17373 
17374             // Destroy secure container
17375             PackageHelper.destroySdDir(cid);
17376         }
17377 
getAllCodePaths()17378         private List<String> getAllCodePaths() {
17379             final File codeFile = new File(getCodePath());
17380             if (codeFile != null && codeFile.exists()) {
17381                 try {
17382                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
17383                     return pkg.getAllCodePaths();
17384                 } catch (PackageParserException e) {
17385                     // Ignored; we tried our best
17386                 }
17387             }
17388             return Collections.EMPTY_LIST;
17389         }
17390 
cleanUpResourcesLI()17391         void cleanUpResourcesLI() {
17392             // Enumerate all code paths before deleting
17393             cleanUpResourcesLI(getAllCodePaths());
17394         }
17395 
cleanUpResourcesLI(List<String> allCodePaths)17396         private void cleanUpResourcesLI(List<String> allCodePaths) {
17397             cleanUp();
17398             removeDexFiles(allCodePaths, instructionSets);
17399         }
17400 
getPackageName()17401         String getPackageName() {
17402             return getAsecPackageName(cid);
17403         }
17404 
doPostDeleteLI(boolean delete)17405         boolean doPostDeleteLI(boolean delete) {
17406             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
17407             final List<String> allCodePaths = getAllCodePaths();
17408             boolean mounted = PackageHelper.isContainerMounted(cid);
17409             if (mounted) {
17410                 // Unmount first
17411                 if (PackageHelper.unMountSdDir(cid)) {
17412                     mounted = false;
17413                 }
17414             }
17415             if (!mounted && delete) {
17416                 cleanUpResourcesLI(allCodePaths);
17417             }
17418             return !mounted;
17419         }
17420 
17421         @Override
doPreCopy()17422         int doPreCopy() {
17423             if (isFwdLocked()) {
17424                 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
17425                         MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
17426                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17427                 }
17428             }
17429 
17430             return PackageManager.INSTALL_SUCCEEDED;
17431         }
17432 
17433         @Override
doPostCopy(int uid)17434         int doPostCopy(int uid) {
17435             if (isFwdLocked()) {
17436                 if (uid < Process.FIRST_APPLICATION_UID
17437                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
17438                                 RES_FILE_NAME)) {
17439                     Slog.e(TAG, "Failed to finalize " + cid);
17440                     PackageHelper.destroySdDir(cid);
17441                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17442                 }
17443             }
17444 
17445             return PackageManager.INSTALL_SUCCEEDED;
17446         }
17447     }
17448 
17449     /**
17450      * Logic to handle movement of existing installed applications.
17451      */
17452     class MoveInstallArgs extends InstallArgs {
17453         private File codeFile;
17454         private File resourceFile;
17455 
17456         /** New install */
MoveInstallArgs(InstallParams params)17457         MoveInstallArgs(InstallParams params) {
17458             super(params.origin, params.move, params.observer, params.installFlags,
17459                     params.installerPackageName, params.volumeUuid,
17460                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17461                     params.grantedRuntimePermissions,
17462                     params.traceMethod, params.traceCookie, params.certificates,
17463                     params.installReason);
17464         }
17465 
copyApk(IMediaContainerService imcs, boolean temp)17466         int copyApk(IMediaContainerService imcs, boolean temp) {
17467             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
17468                     + move.fromUuid + " to " + move.toUuid);
17469             synchronized (mInstaller) {
17470                 try {
17471                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
17472                             move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
17473                 } catch (InstallerException e) {
17474                     Slog.w(TAG, "Failed to move app", e);
17475                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
17476                 }
17477             }
17478 
17479             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
17480             resourceFile = codeFile;
17481             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
17482 
17483             return PackageManager.INSTALL_SUCCEEDED;
17484         }
17485 
doPreInstall(int status)17486         int doPreInstall(int status) {
17487             if (status != PackageManager.INSTALL_SUCCEEDED) {
17488                 cleanUp(move.toUuid);
17489             }
17490             return status;
17491         }
17492 
doRename(int status, PackageParser.Package pkg, String oldCodePath)17493         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17494             if (status != PackageManager.INSTALL_SUCCEEDED) {
17495                 cleanUp(move.toUuid);
17496                 return false;
17497             }
17498 
17499             // Reflect the move in app info
17500             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17501             pkg.setApplicationInfoCodePath(pkg.codePath);
17502             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17503             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17504             pkg.setApplicationInfoResourcePath(pkg.codePath);
17505             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17506             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17507 
17508             return true;
17509         }
17510 
doPostInstall(int status, int uid)17511         int doPostInstall(int status, int uid) {
17512             if (status == PackageManager.INSTALL_SUCCEEDED) {
17513                 cleanUp(move.fromUuid);
17514             } else {
17515                 cleanUp(move.toUuid);
17516             }
17517             return status;
17518         }
17519 
17520         @Override
getCodePath()17521         String getCodePath() {
17522             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17523         }
17524 
17525         @Override
getResourcePath()17526         String getResourcePath() {
17527             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17528         }
17529 
cleanUp(String volumeUuid)17530         private boolean cleanUp(String volumeUuid) {
17531             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
17532                     move.dataAppName);
17533             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
17534             final int[] userIds = sUserManager.getUserIds();
17535             synchronized (mInstallLock) {
17536                 // Clean up both app data and code
17537                 // All package moves are frozen until finished
17538                 for (int userId : userIds) {
17539                     try {
17540                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
17541                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
17542                     } catch (InstallerException e) {
17543                         Slog.w(TAG, String.valueOf(e));
17544                     }
17545                 }
17546                 removeCodePathLI(codeFile);
17547             }
17548             return true;
17549         }
17550 
cleanUpResourcesLI()17551         void cleanUpResourcesLI() {
17552             throw new UnsupportedOperationException();
17553         }
17554 
doPostDeleteLI(boolean delete)17555         boolean doPostDeleteLI(boolean delete) {
17556             throw new UnsupportedOperationException();
17557         }
17558     }
17559 
getAsecPackageName(String packageCid)17560     static String getAsecPackageName(String packageCid) {
17561         int idx = packageCid.lastIndexOf("-");
17562         if (idx == -1) {
17563             return packageCid;
17564         }
17565         return packageCid.substring(0, idx);
17566     }
17567 
17568     // Utility method used to create code paths based on package name and available index.
getNextCodePath(String oldCodePath, String prefix, String suffix)17569     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
17570         String idxStr = "";
17571         int idx = 1;
17572         // Fall back to default value of idx=1 if prefix is not
17573         // part of oldCodePath
17574         if (oldCodePath != null) {
17575             String subStr = oldCodePath;
17576             // Drop the suffix right away
17577             if (suffix != null && subStr.endsWith(suffix)) {
17578                 subStr = subStr.substring(0, subStr.length() - suffix.length());
17579             }
17580             // If oldCodePath already contains prefix find out the
17581             // ending index to either increment or decrement.
17582             int sidx = subStr.lastIndexOf(prefix);
17583             if (sidx != -1) {
17584                 subStr = subStr.substring(sidx + prefix.length());
17585                 if (subStr != null) {
17586                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
17587                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
17588                     }
17589                     try {
17590                         idx = Integer.parseInt(subStr);
17591                         if (idx <= 1) {
17592                             idx++;
17593                         } else {
17594                             idx--;
17595                         }
17596                     } catch(NumberFormatException e) {
17597                     }
17598                 }
17599             }
17600         }
17601         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
17602         return prefix + idxStr;
17603     }
17604 
getNextCodePath(File targetDir, String packageName)17605     private File getNextCodePath(File targetDir, String packageName) {
17606         File result;
17607         SecureRandom random = new SecureRandom();
17608         byte[] bytes = new byte[16];
17609         do {
17610             random.nextBytes(bytes);
17611             String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
17612             result = new File(targetDir, packageName + "-" + suffix);
17613         } while (result.exists());
17614         return result;
17615     }
17616 
17617     // Utility method that returns the relative package path with respect
17618     // to the installation directory. Like say for /data/data/com.test-1.apk
17619     // string com.test-1 is returned.
deriveCodePathName(String codePath)17620     static String deriveCodePathName(String codePath) {
17621         if (codePath == null) {
17622             return null;
17623         }
17624         final File codeFile = new File(codePath);
17625         final String name = codeFile.getName();
17626         if (codeFile.isDirectory()) {
17627             return name;
17628         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
17629             final int lastDot = name.lastIndexOf('.');
17630             return name.substring(0, lastDot);
17631         } else {
17632             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
17633             return null;
17634         }
17635     }
17636 
17637     static class PackageInstalledInfo {
17638         String name;
17639         int uid;
17640         // The set of users that originally had this package installed.
17641         int[] origUsers;
17642         // The set of users that now have this package installed.
17643         int[] newUsers;
17644         PackageParser.Package pkg;
17645         int returnCode;
17646         String returnMsg;
17647         String installerPackageName;
17648         PackageRemovedInfo removedInfo;
17649         ArrayMap<String, PackageInstalledInfo> addedChildPackages;
17650 
setError(int code, String msg)17651         public void setError(int code, String msg) {
17652             setReturnCode(code);
17653             setReturnMessage(msg);
17654             Slog.w(TAG, msg);
17655         }
17656 
setError(String msg, PackageParserException e)17657         public void setError(String msg, PackageParserException e) {
17658             setReturnCode(e.error);
17659             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17660             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17661             for (int i = 0; i < childCount; i++) {
17662                 addedChildPackages.valueAt(i).setError(msg, e);
17663             }
17664             Slog.w(TAG, msg, e);
17665         }
17666 
setError(String msg, PackageManagerException e)17667         public void setError(String msg, PackageManagerException e) {
17668             returnCode = e.error;
17669             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17670             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17671             for (int i = 0; i < childCount; i++) {
17672                 addedChildPackages.valueAt(i).setError(msg, e);
17673             }
17674             Slog.w(TAG, msg, e);
17675         }
17676 
setReturnCode(int returnCode)17677         public void setReturnCode(int returnCode) {
17678             this.returnCode = returnCode;
17679             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17680             for (int i = 0; i < childCount; i++) {
17681                 addedChildPackages.valueAt(i).returnCode = returnCode;
17682             }
17683         }
17684 
setReturnMessage(String returnMsg)17685         private void setReturnMessage(String returnMsg) {
17686             this.returnMsg = returnMsg;
17687             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17688             for (int i = 0; i < childCount; i++) {
17689                 addedChildPackages.valueAt(i).returnMsg = returnMsg;
17690             }
17691         }
17692 
17693         // In some error cases we want to convey more info back to the observer
17694         String origPackage;
17695         String origPermission;
17696     }
17697 
17698     /*
17699      * Install a non-existing package.
17700      */
installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, PackageInstalledInfo res, int installReason)17701     private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
17702             int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
17703             PackageInstalledInfo res, int installReason) {
17704         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
17705 
17706         // Remember this for later, in case we need to rollback this install
17707         String pkgName = pkg.packageName;
17708 
17709         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17710 
17711         synchronized(mPackages) {
17712             final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
17713             if (renamedPackage != null) {
17714                 // A package with the same name is already installed, though
17715                 // it has been renamed to an older name.  The package we
17716                 // are trying to install should be installed as an update to
17717                 // the existing one, but that has not been requested, so bail.
17718                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17719                         + " without first uninstalling package running as "
17720                         + renamedPackage);
17721                 return;
17722             }
17723             if (mPackages.containsKey(pkgName)) {
17724                 // Don't allow installation over an existing package with the same name.
17725                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17726                         + " without first uninstalling.");
17727                 return;
17728             }
17729         }
17730 
17731         try {
17732             PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
17733                     System.currentTimeMillis(), user);
17734 
17735             updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
17736 
17737             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17738                 prepareAppDataAfterInstallLIF(newPackage);
17739 
17740             } else {
17741                 // Remove package from internal structures, but keep around any
17742                 // data that might have already existed
17743                 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
17744                         PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
17745             }
17746         } catch (PackageManagerException e) {
17747             res.setError("Package couldn't be installed in " + pkg.codePath, e);
17748         }
17749 
17750         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17751     }
17752 
shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags)17753     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
17754         // Can't rotate keys during boot or if sharedUser.
17755         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
17756                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
17757             return false;
17758         }
17759         // app is using upgradeKeySets; make sure all are valid
17760         KeySetManagerService ksms = mSettings.mKeySetManagerService;
17761         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17762         for (int i = 0; i < upgradeKeySets.length; i++) {
17763             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17764                 Slog.wtf(TAG, "Package "
17765                          + (oldPs.name != null ? oldPs.name : "<null>")
17766                          + " contains upgrade-key-set reference to unknown key-set: "
17767                          + upgradeKeySets[i]
17768                          + " reverting to signatures check.");
17769                 return false;
17770             }
17771         }
17772         return true;
17773     }
17774 
checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)17775     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
17776         // Upgrade keysets are being used.  Determine if new package has a superset of the
17777         // required keys.
17778         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17779         KeySetManagerService ksms = mSettings.mKeySetManagerService;
17780         for (int i = 0; i < upgradeKeySets.length; i++) {
17781             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17782             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17783                 return true;
17784             }
17785         }
17786         return false;
17787     }
17788 
updateDigest(MessageDigest digest, File file)17789     private static void updateDigest(MessageDigest digest, File file) throws IOException {
17790         try (DigestInputStream digestStream =
17791                 new DigestInputStream(new FileInputStream(file), digest)) {
17792             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17793         }
17794     }
17795 
replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res, int installReason)17796     private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17797             UserHandle user, String installerPackageName, PackageInstalledInfo res,
17798             int installReason) {
17799         final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17800 
17801         final PackageParser.Package oldPackage;
17802         final PackageSetting ps;
17803         final String pkgName = pkg.packageName;
17804         final int[] allUsers;
17805         final int[] installedUsers;
17806 
17807         synchronized(mPackages) {
17808             oldPackage = mPackages.get(pkgName);
17809             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17810 
17811             // don't allow upgrade to target a release SDK from a pre-release SDK
17812             final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17813                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17814             final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17815                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17816             if (oldTargetsPreRelease
17817                     && !newTargetsPreRelease
17818                     && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17819                 Slog.w(TAG, "Can't install package targeting released sdk");
17820                 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17821                 return;
17822             }
17823 
17824             ps = mSettings.mPackages.get(pkgName);
17825 
17826             // verify signatures are valid
17827             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17828                 if (!checkUpgradeKeySetLP(ps, pkg)) {
17829                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17830                             "New package not signed by keys specified by upgrade-keysets: "
17831                                     + pkgName);
17832                     return;
17833                 }
17834             } else {
17835                 // default to original signature matching
17836                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17837                         != PackageManager.SIGNATURE_MATCH) {
17838                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17839                             "New package has a different signature: " + pkgName);
17840                     return;
17841                 }
17842             }
17843 
17844             // don't allow a system upgrade unless the upgrade hash matches
17845             if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17846                 byte[] digestBytes = null;
17847                 try {
17848                     final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17849                     updateDigest(digest, new File(pkg.baseCodePath));
17850                     if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17851                         for (String path : pkg.splitCodePaths) {
17852                             updateDigest(digest, new File(path));
17853                         }
17854                     }
17855                     digestBytes = digest.digest();
17856                 } catch (NoSuchAlgorithmException | IOException e) {
17857                     res.setError(INSTALL_FAILED_INVALID_APK,
17858                             "Could not compute hash: " + pkgName);
17859                     return;
17860                 }
17861                 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17862                     res.setError(INSTALL_FAILED_INVALID_APK,
17863                             "New package fails restrict-update check: " + pkgName);
17864                     return;
17865                 }
17866                 // retain upgrade restriction
17867                 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17868             }
17869 
17870             // Check for shared user id changes
17871             String invalidPackageName =
17872                     getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17873             if (invalidPackageName != null) {
17874                 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17875                         "Package " + invalidPackageName + " tried to change user "
17876                                 + oldPackage.mSharedUserId);
17877                 return;
17878             }
17879 
17880             // In case of rollback, remember per-user/profile install state
17881             allUsers = sUserManager.getUserIds();
17882             installedUsers = ps.queryInstalledUsers(allUsers, true);
17883 
17884             // don't allow an upgrade from full to ephemeral
17885             if (isInstantApp) {
17886                 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17887                     for (int currentUser : allUsers) {
17888                         if (!ps.getInstantApp(currentUser)) {
17889                             // can't downgrade from full to instant
17890                             Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17891                                     + " for user: " + currentUser);
17892                             res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17893                             return;
17894                         }
17895                     }
17896                 } else if (!ps.getInstantApp(user.getIdentifier())) {
17897                     // can't downgrade from full to instant
17898                     Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17899                             + " for user: " + user.getIdentifier());
17900                     res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17901                     return;
17902                 }
17903             }
17904         }
17905 
17906         // Update what is removed
17907         res.removedInfo = new PackageRemovedInfo(this);
17908         res.removedInfo.uid = oldPackage.applicationInfo.uid;
17909         res.removedInfo.removedPackage = oldPackage.packageName;
17910         res.removedInfo.installerPackageName = ps.installerPackageName;
17911         res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17912         res.removedInfo.isUpdate = true;
17913         res.removedInfo.origUsers = installedUsers;
17914         res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17915         for (int i = 0; i < installedUsers.length; i++) {
17916             final int userId = installedUsers[i];
17917             res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17918         }
17919 
17920         final int childCount = (oldPackage.childPackages != null)
17921                 ? oldPackage.childPackages.size() : 0;
17922         for (int i = 0; i < childCount; i++) {
17923             boolean childPackageUpdated = false;
17924             PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17925             final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17926             if (res.addedChildPackages != null) {
17927                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17928                 if (childRes != null) {
17929                     childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17930                     childRes.removedInfo.removedPackage = childPkg.packageName;
17931                     if (childPs != null) {
17932                         childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17933                     }
17934                     childRes.removedInfo.isUpdate = true;
17935                     childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17936                     childPackageUpdated = true;
17937                 }
17938             }
17939             if (!childPackageUpdated) {
17940                 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17941                 childRemovedRes.removedPackage = childPkg.packageName;
17942                 if (childPs != null) {
17943                     childRemovedRes.installerPackageName = childPs.installerPackageName;
17944                 }
17945                 childRemovedRes.isUpdate = false;
17946                 childRemovedRes.dataRemoved = true;
17947                 synchronized (mPackages) {
17948                     if (childPs != null) {
17949                         childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17950                     }
17951                 }
17952                 if (res.removedInfo.removedChildPackages == null) {
17953                     res.removedInfo.removedChildPackages = new ArrayMap<>();
17954                 }
17955                 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17956             }
17957         }
17958 
17959         boolean sysPkg = (isSystemApp(oldPackage));
17960         if (sysPkg) {
17961             // Set the system/privileged flags as needed
17962             final boolean privileged =
17963                     (oldPackage.applicationInfo.privateFlags
17964                             & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17965             final int systemPolicyFlags = policyFlags
17966                     | PackageParser.PARSE_IS_SYSTEM
17967                     | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
17968 
17969             replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17970                     user, allUsers, installerPackageName, res, installReason);
17971         } else {
17972             replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17973                     user, allUsers, installerPackageName, res, installReason);
17974         }
17975     }
17976 
17977     @Override
getPreviousCodePaths(String packageName)17978     public List<String> getPreviousCodePaths(String packageName) {
17979         final int callingUid = Binder.getCallingUid();
17980         final List<String> result = new ArrayList<>();
17981         if (getInstantAppPackageName(callingUid) != null) {
17982             return result;
17983         }
17984         final PackageSetting ps = mSettings.mPackages.get(packageName);
17985         if (ps != null
17986                 && ps.oldCodePaths != null
17987                 && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17988             result.addAll(ps.oldCodePaths);
17989         }
17990         return result;
17991     }
17992 
replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, int[] allUsers, String installerPackageName, PackageInstalledInfo res, int installReason)17993     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17994             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17995             int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17996             int installReason) {
17997         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17998                 + deletedPackage);
17999 
18000         String pkgName = deletedPackage.packageName;
18001         boolean deletedPkg = true;
18002         boolean addedPkg = false;
18003         boolean updatedSettings = false;
18004         final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
18005         final int deleteFlags = PackageManager.DELETE_KEEP_DATA
18006                 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
18007 
18008         final long origUpdateTime = (pkg.mExtras != null)
18009                 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
18010 
18011         // First delete the existing package while retaining the data directory
18012         if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
18013                 res.removedInfo, true, pkg)) {
18014             // If the existing package wasn't successfully deleted
18015             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
18016             deletedPkg = false;
18017         } else {
18018             // Successfully deleted the old package; proceed with replace.
18019 
18020             // If deleted package lived in a container, give users a chance to
18021             // relinquish resources before killing.
18022             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
18023                 if (DEBUG_INSTALL) {
18024                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
18025                 }
18026                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
18027                 final ArrayList<String> pkgList = new ArrayList<String>(1);
18028                 pkgList.add(deletedPackage.applicationInfo.packageName);
18029                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
18030             }
18031 
18032             clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
18033                     | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18034             clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
18035 
18036             try {
18037                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
18038                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
18039                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
18040                         installReason);
18041 
18042                 // Update the in-memory copy of the previous code paths.
18043                 PackageSetting ps = mSettings.mPackages.get(pkgName);
18044                 if (!killApp) {
18045                     if (ps.oldCodePaths == null) {
18046                         ps.oldCodePaths = new ArraySet<>();
18047                     }
18048                     Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
18049                     if (deletedPackage.splitCodePaths != null) {
18050                         Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
18051                     }
18052                 } else {
18053                     ps.oldCodePaths = null;
18054                 }
18055                 if (ps.childPackageNames != null) {
18056                     for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
18057                         final String childPkgName = ps.childPackageNames.get(i);
18058                         final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
18059                         childPs.oldCodePaths = ps.oldCodePaths;
18060                     }
18061                 }
18062                 // set instant app status, but, only if it's explicitly specified
18063                 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
18064                 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
18065                 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
18066                 prepareAppDataAfterInstallLIF(newPackage);
18067                 addedPkg = true;
18068                 mDexManager.notifyPackageUpdated(newPackage.packageName,
18069                         newPackage.baseCodePath, newPackage.splitCodePaths);
18070             } catch (PackageManagerException e) {
18071                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
18072             }
18073         }
18074 
18075         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
18076             if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
18077 
18078             // Revert all internal state mutations and added folders for the failed install
18079             if (addedPkg) {
18080                 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
18081                         res.removedInfo, true, null);
18082             }
18083 
18084             // Restore the old package
18085             if (deletedPkg) {
18086                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
18087                 File restoreFile = new File(deletedPackage.codePath);
18088                 // Parse old package
18089                 boolean oldExternal = isExternal(deletedPackage);
18090                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
18091                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
18092                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
18093                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
18094                 try {
18095                     scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
18096                             null);
18097                 } catch (PackageManagerException e) {
18098                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
18099                             + e.getMessage());
18100                     return;
18101                 }
18102 
18103                 synchronized (mPackages) {
18104                     // Ensure the installer package name up to date
18105                     setInstallerPackageNameLPw(deletedPackage, installerPackageName);
18106 
18107                     // Update permissions for restored package
18108                     updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
18109 
18110                     mSettings.writeLPr();
18111                 }
18112 
18113                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
18114             }
18115         } else {
18116             synchronized (mPackages) {
18117                 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
18118                 if (ps != null) {
18119                     res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18120                     if (res.removedInfo.removedChildPackages != null) {
18121                         final int childCount = res.removedInfo.removedChildPackages.size();
18122                         // Iterate in reverse as we may modify the collection
18123                         for (int i = childCount - 1; i >= 0; i--) {
18124                             String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
18125                             if (res.addedChildPackages.containsKey(childPackageName)) {
18126                                 res.removedInfo.removedChildPackages.removeAt(i);
18127                             } else {
18128                                 PackageRemovedInfo childInfo = res.removedInfo
18129                                         .removedChildPackages.valueAt(i);
18130                                 childInfo.removedForAllUsers = mPackages.get(
18131                                         childInfo.removedPackage) == null;
18132                             }
18133                         }
18134                     }
18135                 }
18136             }
18137         }
18138     }
18139 
replaceSystemPackageLIF(PackageParser.Package deletedPackage, PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, int[] allUsers, String installerPackageName, PackageInstalledInfo res, int installReason)18140     private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
18141             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
18142             int[] allUsers, String installerPackageName, PackageInstalledInfo res,
18143             int installReason) {
18144         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
18145                 + ", old=" + deletedPackage);
18146 
18147         final boolean disabledSystem;
18148 
18149         // Remove existing system package
18150         removePackageLI(deletedPackage, true);
18151 
18152         synchronized (mPackages) {
18153             disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
18154         }
18155         if (!disabledSystem) {
18156             // We didn't need to disable the .apk as a current system package,
18157             // which means we are replacing another update that is already
18158             // installed.  We need to make sure to delete the older one's .apk.
18159             res.removedInfo.args = createInstallArgsForExisting(0,
18160                     deletedPackage.applicationInfo.getCodePath(),
18161                     deletedPackage.applicationInfo.getResourcePath(),
18162                     getAppDexInstructionSets(deletedPackage.applicationInfo));
18163         } else {
18164             res.removedInfo.args = null;
18165         }
18166 
18167         // Successfully disabled the old package. Now proceed with re-installation
18168         clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
18169                 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18170         clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
18171 
18172         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18173         pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
18174                 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
18175 
18176         PackageParser.Package newPackage = null;
18177         try {
18178             // Add the package to the internal data structures
18179             newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
18180 
18181             // Set the update and install times
18182             PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
18183             setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
18184                     System.currentTimeMillis());
18185 
18186             // Update the package dynamic state if succeeded
18187             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18188                 // Now that the install succeeded make sure we remove data
18189                 // directories for any child package the update removed.
18190                 final int deletedChildCount = (deletedPackage.childPackages != null)
18191                         ? deletedPackage.childPackages.size() : 0;
18192                 final int newChildCount = (newPackage.childPackages != null)
18193                         ? newPackage.childPackages.size() : 0;
18194                 for (int i = 0; i < deletedChildCount; i++) {
18195                     PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
18196                     boolean childPackageDeleted = true;
18197                     for (int j = 0; j < newChildCount; j++) {
18198                         PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
18199                         if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
18200                             childPackageDeleted = false;
18201                             break;
18202                         }
18203                     }
18204                     if (childPackageDeleted) {
18205                         PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
18206                                 deletedChildPkg.packageName);
18207                         if (ps != null && res.removedInfo.removedChildPackages != null) {
18208                             PackageRemovedInfo removedChildRes = res.removedInfo
18209                                     .removedChildPackages.get(deletedChildPkg.packageName);
18210                             removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
18211                             removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
18212                         }
18213                     }
18214                 }
18215 
18216                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
18217                         installReason);
18218                 prepareAppDataAfterInstallLIF(newPackage);
18219 
18220                 mDexManager.notifyPackageUpdated(newPackage.packageName,
18221                             newPackage.baseCodePath, newPackage.splitCodePaths);
18222             }
18223         } catch (PackageManagerException e) {
18224             res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
18225             res.setError("Package couldn't be installed in " + pkg.codePath, e);
18226         }
18227 
18228         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
18229             // Re installation failed. Restore old information
18230             // Remove new pkg information
18231             if (newPackage != null) {
18232                 removeInstalledPackageLI(newPackage, true);
18233             }
18234             // Add back the old system package
18235             try {
18236                 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
18237             } catch (PackageManagerException e) {
18238                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
18239             }
18240 
18241             synchronized (mPackages) {
18242                 if (disabledSystem) {
18243                     enableSystemPackageLPw(deletedPackage);
18244                 }
18245 
18246                 // Ensure the installer package name up to date
18247                 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
18248 
18249                 // Update permissions for restored package
18250                 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
18251 
18252                 mSettings.writeLPr();
18253             }
18254 
18255             Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
18256                     + " after failed upgrade");
18257         }
18258     }
18259 
18260     /**
18261      * Checks whether the parent or any of the child packages have a change shared
18262      * user. For a package to be a valid update the shred users of the parent and
18263      * the children should match. We may later support changing child shared users.
18264      * @param oldPkg The updated package.
18265      * @param newPkg The update package.
18266      * @return The shared user that change between the versions.
18267      */
getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, PackageParser.Package newPkg)18268     private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
18269             PackageParser.Package newPkg) {
18270         // Check parent shared user
18271         if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
18272             return newPkg.packageName;
18273         }
18274         // Check child shared users
18275         final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18276         final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
18277         for (int i = 0; i < newChildCount; i++) {
18278             PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
18279             // If this child was present, did it have the same shared user?
18280             for (int j = 0; j < oldChildCount; j++) {
18281                 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
18282                 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
18283                         && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
18284                     return newChildPkg.packageName;
18285                 }
18286             }
18287         }
18288         return null;
18289     }
18290 
removeNativeBinariesLI(PackageSetting ps)18291     private void removeNativeBinariesLI(PackageSetting ps) {
18292         // Remove the lib path for the parent package
18293         if (ps != null) {
18294             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
18295             // Remove the lib path for the child packages
18296             final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18297             for (int i = 0; i < childCount; i++) {
18298                 PackageSetting childPs = null;
18299                 synchronized (mPackages) {
18300                     childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18301                 }
18302                 if (childPs != null) {
18303                     NativeLibraryHelper.removeNativeBinariesLI(childPs
18304                             .legacyNativeLibraryPathString);
18305                 }
18306             }
18307         }
18308     }
18309 
enableSystemPackageLPw(PackageParser.Package pkg)18310     private void enableSystemPackageLPw(PackageParser.Package pkg) {
18311         // Enable the parent package
18312         mSettings.enableSystemPackageLPw(pkg.packageName);
18313         // Enable the child packages
18314         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18315         for (int i = 0; i < childCount; i++) {
18316             PackageParser.Package childPkg = pkg.childPackages.get(i);
18317             mSettings.enableSystemPackageLPw(childPkg.packageName);
18318         }
18319     }
18320 
disableSystemPackageLPw(PackageParser.Package oldPkg, PackageParser.Package newPkg)18321     private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
18322             PackageParser.Package newPkg) {
18323         // Disable the parent package (parent always replaced)
18324         boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
18325         // Disable the child packages
18326         final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18327         for (int i = 0; i < childCount; i++) {
18328             PackageParser.Package childPkg = oldPkg.childPackages.get(i);
18329             final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
18330             disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
18331         }
18332         return disabled;
18333     }
18334 
setInstallerPackageNameLPw(PackageParser.Package pkg, String installerPackageName)18335     private void setInstallerPackageNameLPw(PackageParser.Package pkg,
18336             String installerPackageName) {
18337         // Enable the parent package
18338         mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
18339         // Enable the child packages
18340         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18341         for (int i = 0; i < childCount; i++) {
18342             PackageParser.Package childPkg = pkg.childPackages.get(i);
18343             mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
18344         }
18345     }
18346 
revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds)18347     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
18348         // Collect all used permissions in the UID
18349         ArraySet<String> usedPermissions = new ArraySet<>();
18350         final int packageCount = su.packages.size();
18351         for (int i = 0; i < packageCount; i++) {
18352             PackageSetting ps = su.packages.valueAt(i);
18353             if (ps.pkg == null) {
18354                 continue;
18355             }
18356             final int requestedPermCount = ps.pkg.requestedPermissions.size();
18357             for (int j = 0; j < requestedPermCount; j++) {
18358                 String permission = ps.pkg.requestedPermissions.get(j);
18359                 BasePermission bp = mSettings.mPermissions.get(permission);
18360                 if (bp != null) {
18361                     usedPermissions.add(permission);
18362                 }
18363             }
18364         }
18365 
18366         PermissionsState permissionsState = su.getPermissionsState();
18367         // Prune install permissions
18368         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
18369         final int installPermCount = installPermStates.size();
18370         for (int i = installPermCount - 1; i >= 0;  i--) {
18371             PermissionState permissionState = installPermStates.get(i);
18372             if (!usedPermissions.contains(permissionState.getName())) {
18373                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18374                 if (bp != null) {
18375                     permissionsState.revokeInstallPermission(bp);
18376                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
18377                             PackageManager.MASK_PERMISSION_FLAGS, 0);
18378                 }
18379             }
18380         }
18381 
18382         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
18383 
18384         // Prune runtime permissions
18385         for (int userId : allUserIds) {
18386             List<PermissionState> runtimePermStates = permissionsState
18387                     .getRuntimePermissionStates(userId);
18388             final int runtimePermCount = runtimePermStates.size();
18389             for (int i = runtimePermCount - 1; i >= 0; i--) {
18390                 PermissionState permissionState = runtimePermStates.get(i);
18391                 if (!usedPermissions.contains(permissionState.getName())) {
18392                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18393                     if (bp != null) {
18394                         permissionsState.revokeRuntimePermission(bp, userId);
18395                         permissionsState.updatePermissionFlags(bp, userId,
18396                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
18397                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
18398                                 runtimePermissionChangedUserIds, userId);
18399                     }
18400                 }
18401             }
18402         }
18403 
18404         return runtimePermissionChangedUserIds;
18405     }
18406 
updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason)18407     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
18408             int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
18409         // Update the parent package setting
18410         updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
18411                 res, user, installReason);
18412         // Update the child packages setting
18413         final int childCount = (newPackage.childPackages != null)
18414                 ? newPackage.childPackages.size() : 0;
18415         for (int i = 0; i < childCount; i++) {
18416             PackageParser.Package childPackage = newPackage.childPackages.get(i);
18417             PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
18418             updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
18419                     childRes.origUsers, childRes, user, installReason);
18420         }
18421     }
18422 
updateSettingsInternalLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, int[] installedForUsers, PackageInstalledInfo res, UserHandle user, int installReason)18423     private void updateSettingsInternalLI(PackageParser.Package newPackage,
18424             String installerPackageName, int[] allUsers, int[] installedForUsers,
18425             PackageInstalledInfo res, UserHandle user, int installReason) {
18426         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
18427 
18428         String pkgName = newPackage.packageName;
18429         synchronized (mPackages) {
18430             //write settings. the installStatus will be incomplete at this stage.
18431             //note that the new package setting would have already been
18432             //added to mPackages. It hasn't been persisted yet.
18433             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
18434             // TODO: Remove this write? It's also written at the end of this method
18435             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18436             mSettings.writeLPr();
18437             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18438         }
18439 
18440         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
18441         synchronized (mPackages) {
18442             updatePermissionsLPw(newPackage.packageName, newPackage,
18443                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
18444                             ? UPDATE_PERMISSIONS_ALL : 0));
18445             // For system-bundled packages, we assume that installing an upgraded version
18446             // of the package implies that the user actually wants to run that new code,
18447             // so we enable the package.
18448             PackageSetting ps = mSettings.mPackages.get(pkgName);
18449             final int userId = user.getIdentifier();
18450             if (ps != null) {
18451                 if (isSystemApp(newPackage)) {
18452                     if (DEBUG_INSTALL) {
18453                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
18454                     }
18455                     // Enable system package for requested users
18456                     if (res.origUsers != null) {
18457                         for (int origUserId : res.origUsers) {
18458                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
18459                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
18460                                         origUserId, installerPackageName);
18461                             }
18462                         }
18463                     }
18464                     // Also convey the prior install/uninstall state
18465                     if (allUsers != null && installedForUsers != null) {
18466                         for (int currentUserId : allUsers) {
18467                             final boolean installed = ArrayUtils.contains(
18468                                     installedForUsers, currentUserId);
18469                             if (DEBUG_INSTALL) {
18470                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
18471                             }
18472                             ps.setInstalled(installed, currentUserId);
18473                         }
18474                         // these install state changes will be persisted in the
18475                         // upcoming call to mSettings.writeLPr().
18476                     }
18477                 }
18478                 // It's implied that when a user requests installation, they want the app to be
18479                 // installed and enabled.
18480                 if (userId != UserHandle.USER_ALL) {
18481                     ps.setInstalled(true, userId);
18482                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
18483                 }
18484 
18485                 // When replacing an existing package, preserve the original install reason for all
18486                 // users that had the package installed before.
18487                 final Set<Integer> previousUserIds = new ArraySet<>();
18488                 if (res.removedInfo != null && res.removedInfo.installReasons != null) {
18489                     final int installReasonCount = res.removedInfo.installReasons.size();
18490                     for (int i = 0; i < installReasonCount; i++) {
18491                         final int previousUserId = res.removedInfo.installReasons.keyAt(i);
18492                         final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
18493                         ps.setInstallReason(previousInstallReason, previousUserId);
18494                         previousUserIds.add(previousUserId);
18495                     }
18496                 }
18497 
18498                 // Set install reason for users that are having the package newly installed.
18499                 if (userId == UserHandle.USER_ALL) {
18500                     for (int currentUserId : sUserManager.getUserIds()) {
18501                         if (!previousUserIds.contains(currentUserId)) {
18502                             ps.setInstallReason(installReason, currentUserId);
18503                         }
18504                     }
18505                 } else if (!previousUserIds.contains(userId)) {
18506                     ps.setInstallReason(installReason, userId);
18507                 }
18508                 mSettings.writeKernelMappingLPr(ps);
18509             }
18510             res.name = pkgName;
18511             res.uid = newPackage.applicationInfo.uid;
18512             res.pkg = newPackage;
18513             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
18514             mSettings.setInstallerPackageName(pkgName, installerPackageName);
18515             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18516             //to update install status
18517             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18518             mSettings.writeLPr();
18519             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18520         }
18521 
18522         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18523     }
18524 
installPackageTracedLI(InstallArgs args, PackageInstalledInfo res)18525     private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
18526         try {
18527             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
18528             installPackageLI(args, res);
18529         } finally {
18530             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18531         }
18532     }
18533 
installPackageLI(InstallArgs args, PackageInstalledInfo res)18534     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
18535         final int installFlags = args.installFlags;
18536         final String installerPackageName = args.installerPackageName;
18537         final String volumeUuid = args.volumeUuid;
18538         final File tmpPackageFile = new File(args.getCodePath());
18539         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
18540         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
18541                 || (args.volumeUuid != null));
18542         final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
18543         final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
18544         final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
18545         final boolean virtualPreload =
18546                 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
18547         boolean replace = false;
18548         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
18549         if (args.move != null) {
18550             // moving a complete application; perform an initial scan on the new install location
18551             scanFlags |= SCAN_INITIAL;
18552         }
18553         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
18554             scanFlags |= SCAN_DONT_KILL_APP;
18555         }
18556         if (instantApp) {
18557             scanFlags |= SCAN_AS_INSTANT_APP;
18558         }
18559         if (fullApp) {
18560             scanFlags |= SCAN_AS_FULL_APP;
18561         }
18562         if (virtualPreload) {
18563             scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
18564         }
18565 
18566         // Result object to be returned
18567         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18568         res.installerPackageName = installerPackageName;
18569 
18570         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
18571 
18572         // Sanity check
18573         if (instantApp && (forwardLocked || onExternal)) {
18574             Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
18575                     + " external=" + onExternal);
18576             res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
18577             return;
18578         }
18579 
18580         // Retrieve PackageSettings and parse package
18581         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
18582                 | PackageParser.PARSE_ENFORCE_CODE
18583                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
18584                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
18585                 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
18586                 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
18587         PackageParser pp = new PackageParser();
18588         pp.setSeparateProcesses(mSeparateProcesses);
18589         pp.setDisplayMetrics(mMetrics);
18590         pp.setCallback(mPackageParserCallback);
18591 
18592         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
18593         final PackageParser.Package pkg;
18594         try {
18595             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
18596         } catch (PackageParserException e) {
18597             res.setError("Failed parse during installPackageLI", e);
18598             return;
18599         } finally {
18600             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18601         }
18602 
18603         // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
18604         if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
18605             Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
18606             res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18607                     "Instant app package must target O");
18608             return;
18609         }
18610         if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
18611             Slog.w(TAG, "Instant app package " + pkg.packageName
18612                     + " does not target targetSandboxVersion 2");
18613             res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18614                     "Instant app package must use targetSanboxVersion 2");
18615             return;
18616         }
18617 
18618         if (pkg.applicationInfo.isStaticSharedLibrary()) {
18619             // Static shared libraries have synthetic package names
18620             renameStaticSharedLibraryPackage(pkg);
18621 
18622             // No static shared libs on external storage
18623             if (onExternal) {
18624                 Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
18625                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18626                         "Packages declaring static-shared libs cannot be updated");
18627                 return;
18628             }
18629         }
18630 
18631         // If we are installing a clustered package add results for the children
18632         if (pkg.childPackages != null) {
18633             synchronized (mPackages) {
18634                 final int childCount = pkg.childPackages.size();
18635                 for (int i = 0; i < childCount; i++) {
18636                     PackageParser.Package childPkg = pkg.childPackages.get(i);
18637                     PackageInstalledInfo childRes = new PackageInstalledInfo();
18638                     childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18639                     childRes.pkg = childPkg;
18640                     childRes.name = childPkg.packageName;
18641                     PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18642                     if (childPs != null) {
18643                         childRes.origUsers = childPs.queryInstalledUsers(
18644                                 sUserManager.getUserIds(), true);
18645                     }
18646                     if ((mPackages.containsKey(childPkg.packageName))) {
18647                         childRes.removedInfo = new PackageRemovedInfo(this);
18648                         childRes.removedInfo.removedPackage = childPkg.packageName;
18649                         childRes.removedInfo.installerPackageName = childPs.installerPackageName;
18650                     }
18651                     if (res.addedChildPackages == null) {
18652                         res.addedChildPackages = new ArrayMap<>();
18653                     }
18654                     res.addedChildPackages.put(childPkg.packageName, childRes);
18655                 }
18656             }
18657         }
18658 
18659         // If package doesn't declare API override, mark that we have an install
18660         // time CPU ABI override.
18661         if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
18662             pkg.cpuAbiOverride = args.abiOverride;
18663         }
18664 
18665         String pkgName = res.name = pkg.packageName;
18666         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
18667             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
18668                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
18669                 return;
18670             }
18671         }
18672 
18673         try {
18674             // either use what we've been given or parse directly from the APK
18675             if (args.certificates != null) {
18676                 try {
18677                     PackageParser.populateCertificates(pkg, args.certificates);
18678                 } catch (PackageParserException e) {
18679                     // there was something wrong with the certificates we were given;
18680                     // try to pull them from the APK
18681                     PackageParser.collectCertificates(pkg, parseFlags);
18682                 }
18683             } else {
18684                 PackageParser.collectCertificates(pkg, parseFlags);
18685             }
18686         } catch (PackageParserException e) {
18687             res.setError("Failed collect during installPackageLI", e);
18688             return;
18689         }
18690 
18691         // Get rid of all references to package scan path via parser.
18692         pp = null;
18693         String oldCodePath = null;
18694         boolean systemApp = false;
18695         synchronized (mPackages) {
18696             // Check if installing already existing package
18697             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
18698                 String oldName = mSettings.getRenamedPackageLPr(pkgName);
18699                 if (pkg.mOriginalPackages != null
18700                         && pkg.mOriginalPackages.contains(oldName)
18701                         && mPackages.containsKey(oldName)) {
18702                     // This package is derived from an original package,
18703                     // and this device has been updating from that original
18704                     // name.  We must continue using the original name, so
18705                     // rename the new package here.
18706                     pkg.setPackageName(oldName);
18707                     pkgName = pkg.packageName;
18708                     replace = true;
18709                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
18710                             + oldName + " pkgName=" + pkgName);
18711                 } else if (mPackages.containsKey(pkgName)) {
18712                     // This package, under its official name, already exists
18713                     // on the device; we should replace it.
18714                     replace = true;
18715                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
18716                 }
18717 
18718                 // Child packages are installed through the parent package
18719                 if (pkg.parentPackage != null) {
18720                     res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18721                             "Package " + pkg.packageName + " is child of package "
18722                                     + pkg.parentPackage.parentPackage + ". Child packages "
18723                                     + "can be updated only through the parent package.");
18724                     return;
18725                 }
18726 
18727                 if (replace) {
18728                     // Prevent apps opting out from runtime permissions
18729                     PackageParser.Package oldPackage = mPackages.get(pkgName);
18730                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
18731                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
18732                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
18733                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
18734                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
18735                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
18736                                         + " doesn't support runtime permissions but the old"
18737                                         + " target SDK " + oldTargetSdk + " does.");
18738                         return;
18739                     }
18740                     // Prevent apps from downgrading their targetSandbox.
18741                     final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
18742                     final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
18743                     if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
18744                         res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18745                                 "Package " + pkg.packageName + " new target sandbox "
18746                                 + newTargetSandbox + " is incompatible with the previous value of"
18747                                 + oldTargetSandbox + ".");
18748                         return;
18749                     }
18750 
18751                     // Prevent installing of child packages
18752                     if (oldPackage.parentPackage != null) {
18753                         res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18754                                 "Package " + pkg.packageName + " is child of package "
18755                                         + oldPackage.parentPackage + ". Child packages "
18756                                         + "can be updated only through the parent package.");
18757                         return;
18758                     }
18759                 }
18760             }
18761 
18762             PackageSetting ps = mSettings.mPackages.get(pkgName);
18763             if (ps != null) {
18764                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
18765 
18766                 // Static shared libs have same package with different versions where
18767                 // we internally use a synthetic package name to allow multiple versions
18768                 // of the same package, therefore we need to compare signatures against
18769                 // the package setting for the latest library version.
18770                 PackageSetting signatureCheckPs = ps;
18771                 if (pkg.applicationInfo.isStaticSharedLibrary()) {
18772                     SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18773                     if (libraryEntry != null) {
18774                         signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18775                     }
18776                 }
18777 
18778                 // Quick sanity check that we're signed correctly if updating;
18779                 // we'll check this again later when scanning, but we want to
18780                 // bail early here before tripping over redefined permissions.
18781                 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18782                     if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18783                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18784                                 + pkg.packageName + " upgrade keys do not match the "
18785                                 + "previously installed version");
18786                         return;
18787                     }
18788                 } else {
18789                     try {
18790                         verifySignaturesLP(signatureCheckPs, pkg);
18791                     } catch (PackageManagerException e) {
18792                         res.setError(e.error, e.getMessage());
18793                         return;
18794                     }
18795                 }
18796 
18797                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18798                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18799                     systemApp = (ps.pkg.applicationInfo.flags &
18800                             ApplicationInfo.FLAG_SYSTEM) != 0;
18801                 }
18802                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18803             }
18804 
18805             int N = pkg.permissions.size();
18806             for (int i = N-1; i >= 0; i--) {
18807                 PackageParser.Permission perm = pkg.permissions.get(i);
18808                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18809 
18810                 // Don't allow anyone but the system to define ephemeral permissions.
18811                 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
18812                         && !systemApp) {
18813                     Slog.w(TAG, "Non-System package " + pkg.packageName
18814                             + " attempting to delcare ephemeral permission "
18815                             + perm.info.name + "; Removing ephemeral.");
18816                     perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
18817                 }
18818                 // Check whether the newly-scanned package wants to define an already-defined perm
18819                 if (bp != null) {
18820                     // If the defining package is signed with our cert, it's okay.  This
18821                     // also includes the "updating the same package" case, of course.
18822                     // "updating same package" could also involve key-rotation.
18823                     final boolean sigsOk;
18824                     if (bp.sourcePackage.equals(pkg.packageName)
18825                             && (bp.packageSetting instanceof PackageSetting)
18826                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
18827                                     scanFlags))) {
18828                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
18829                     } else {
18830                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
18831                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18832                     }
18833                     if (!sigsOk) {
18834                         // If the owning package is the system itself, we log but allow
18835                         // install to proceed; we fail the install on all other permission
18836                         // redefinitions.
18837                         if (!bp.sourcePackage.equals("android")) {
18838                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18839                                     + pkg.packageName + " attempting to redeclare permission "
18840                                     + perm.info.name + " already owned by " + bp.sourcePackage);
18841                             res.origPermission = perm.info.name;
18842                             res.origPackage = bp.sourcePackage;
18843                             return;
18844                         } else {
18845                             Slog.w(TAG, "Package " + pkg.packageName
18846                                     + " attempting to redeclare system permission "
18847                                     + perm.info.name + "; ignoring new declaration");
18848                             pkg.permissions.remove(i);
18849                         }
18850                     } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18851                         // Prevent apps to change protection level to dangerous from any other
18852                         // type as this would allow a privilege escalation where an app adds a
18853                         // normal/signature permission in other app's group and later redefines
18854                         // it as dangerous leading to the group auto-grant.
18855                         if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18856                                 == PermissionInfo.PROTECTION_DANGEROUS) {
18857                             if (bp != null && !bp.isRuntime()) {
18858                                 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18859                                         + "non-runtime permission " + perm.info.name
18860                                         + " to runtime; keeping old protection level");
18861                                 perm.info.protectionLevel = bp.protectionLevel;
18862                             }
18863                         }
18864                     }
18865                 }
18866             }
18867         }
18868 
18869         if (systemApp) {
18870             if (onExternal) {
18871                 // Abort update; system app can't be replaced with app on sdcard
18872                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18873                         "Cannot install updates to system apps on sdcard");
18874                 return;
18875             } else if (instantApp) {
18876                 // Abort update; system app can't be replaced with an instant app
18877                 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18878                         "Cannot update a system app with an instant app");
18879                 return;
18880             }
18881         }
18882 
18883         if (args.move != null) {
18884             // We did an in-place move, so dex is ready to roll
18885             scanFlags |= SCAN_NO_DEX;
18886             scanFlags |= SCAN_MOVE;
18887 
18888             synchronized (mPackages) {
18889                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
18890                 if (ps == null) {
18891                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18892                             "Missing settings for moved package " + pkgName);
18893                 }
18894 
18895                 // We moved the entire application as-is, so bring over the
18896                 // previously derived ABI information.
18897                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18898                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18899             }
18900 
18901         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18902             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18903             scanFlags |= SCAN_NO_DEX;
18904 
18905             try {
18906                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18907                     args.abiOverride : pkg.cpuAbiOverride);
18908                 final boolean extractNativeLibs = !pkg.isLibrary();
18909                 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18910                         extractNativeLibs, mAppLib32InstallDir);
18911             } catch (PackageManagerException pme) {
18912                 Slog.e(TAG, "Error deriving application ABI", pme);
18913                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18914                 return;
18915             }
18916 
18917             // Shared libraries for the package need to be updated.
18918             synchronized (mPackages) {
18919                 try {
18920                     updateSharedLibrariesLPr(pkg, null);
18921                 } catch (PackageManagerException e) {
18922                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18923                 }
18924             }
18925         }
18926 
18927         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18928             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18929             return;
18930         }
18931 
18932         // Verify if we need to dexopt the app.
18933         //
18934         // NOTE: it is *important* to call dexopt after doRename which will sync the
18935         // package data from PackageParser.Package and its corresponding ApplicationInfo.
18936         //
18937         // We only need to dexopt if the package meets ALL of the following conditions:
18938         //   1) it is not forward locked.
18939         //   2) it is not on on an external ASEC container.
18940         //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
18941         //
18942         // Note that we do not dexopt instant apps by default. dexopt can take some time to
18943         // complete, so we skip this step during installation. Instead, we'll take extra time
18944         // the first time the instant app starts. It's preferred to do it this way to provide
18945         // continuous progress to the useur instead of mysteriously blocking somewhere in the
18946         // middle of running an instant app. The default behaviour can be overridden
18947         // via gservices.
18948         final boolean performDexopt = !forwardLocked
18949             && !pkg.applicationInfo.isExternalAsec()
18950             && (!instantApp || Global.getInt(mContext.getContentResolver(),
18951                     Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
18952 
18953         if (performDexopt) {
18954             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18955             // Do not run PackageDexOptimizer through the local performDexOpt
18956             // method because `pkg` may not be in `mPackages` yet.
18957             //
18958             // Also, don't fail application installs if the dexopt step fails.
18959             DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
18960                 REASON_INSTALL,
18961                 DexoptOptions.DEXOPT_BOOT_COMPLETE);
18962             mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18963                 null /* instructionSets */,
18964                 getOrCreateCompilerPackageStats(pkg),
18965                 mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
18966                 dexoptOptions);
18967             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18968         }
18969 
18970         // Notify BackgroundDexOptService that the package has been changed.
18971         // If this is an update of a package which used to fail to compile,
18972         // BackgroundDexOptService will remove it from its blacklist.
18973         // TODO: Layering violation
18974         BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18975 
18976         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18977 
18978         try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18979                 "installPackageLI")) {
18980             if (replace) {
18981                 if (pkg.applicationInfo.isStaticSharedLibrary()) {
18982                     // Static libs have a synthetic package name containing the version
18983                     // and cannot be updated as an update would get a new package name,
18984                     // unless this is the exact same version code which is useful for
18985                     // development.
18986                     PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18987                     if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18988                         res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18989                                 + "static-shared libs cannot be updated");
18990                         return;
18991                     }
18992                 }
18993                 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18994                         installerPackageName, res, args.installReason);
18995             } else {
18996                 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18997                         args.user, installerPackageName, volumeUuid, res, args.installReason);
18998             }
18999         }
19000 
19001         synchronized (mPackages) {
19002             final PackageSetting ps = mSettings.mPackages.get(pkgName);
19003             if (ps != null) {
19004                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
19005                 ps.setUpdateAvailable(false /*updateAvailable*/);
19006             }
19007 
19008             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
19009             for (int i = 0; i < childCount; i++) {
19010                 PackageParser.Package childPkg = pkg.childPackages.get(i);
19011                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
19012                 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
19013                 if (childPs != null) {
19014                     childRes.newUsers = childPs.queryInstalledUsers(
19015                             sUserManager.getUserIds(), true);
19016                 }
19017             }
19018 
19019             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
19020                 updateSequenceNumberLP(ps, res.newUsers);
19021                 updateInstantAppInstallerLocked(pkgName);
19022             }
19023         }
19024     }
19025 
startIntentFilterVerifications(int userId, boolean replacing, PackageParser.Package pkg)19026     private void startIntentFilterVerifications(int userId, boolean replacing,
19027             PackageParser.Package pkg) {
19028         if (mIntentFilterVerifierComponent == null) {
19029             Slog.w(TAG, "No IntentFilter verification will not be done as "
19030                     + "there is no IntentFilterVerifier available!");
19031             return;
19032         }
19033 
19034         final int verifierUid = getPackageUid(
19035                 mIntentFilterVerifierComponent.getPackageName(),
19036                 MATCH_DEBUG_TRIAGED_MISSING,
19037                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
19038 
19039         Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
19040         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
19041         mHandler.sendMessage(msg);
19042 
19043         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
19044         for (int i = 0; i < childCount; i++) {
19045             PackageParser.Package childPkg = pkg.childPackages.get(i);
19046             msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
19047             msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
19048             mHandler.sendMessage(msg);
19049         }
19050     }
19051 
verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, PackageParser.Package pkg)19052     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
19053             PackageParser.Package pkg) {
19054         int size = pkg.activities.size();
19055         if (size == 0) {
19056             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19057                     "No activity, so no need to verify any IntentFilter!");
19058             return;
19059         }
19060 
19061         final boolean hasDomainURLs = hasDomainURLs(pkg);
19062         if (!hasDomainURLs) {
19063             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19064                     "No domain URLs, so no need to verify any IntentFilter!");
19065             return;
19066         }
19067 
19068         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
19069                 + " if any IntentFilter from the " + size
19070                 + " Activities needs verification ...");
19071 
19072         int count = 0;
19073         final String packageName = pkg.packageName;
19074         boolean handlesWebUris = false;
19075         ArraySet<String> domains = new ArraySet<>();
19076         final boolean previouslyVerified;
19077         boolean hostSetExpanded = false;
19078         boolean needToRunVerify = false;
19079         synchronized (mPackages) {
19080             // If this is a new install and we see that we've already run verification for this
19081             // package, we have nothing to do: it means the state was restored from backup.
19082             IntentFilterVerificationInfo ivi =
19083                     mSettings.getIntentFilterVerificationLPr(packageName);
19084             previouslyVerified = (ivi != null);
19085             if (!replacing && previouslyVerified) {
19086                 if (DEBUG_DOMAIN_VERIFICATION) {
19087                     Slog.i(TAG, "Package " + packageName + " already verified: status="
19088                             + ivi.getStatusString());
19089                 }
19090                 return;
19091             }
19092 
19093             if (DEBUG_DOMAIN_VERIFICATION) {
19094                 Slog.i(TAG, "    Previous verified hosts: "
19095                         + (ivi == null ? "[none]" : ivi.getDomainsString()));
19096             }
19097 
19098             // If any filters need to be verified, then all need to be.  In addition, we need to
19099             // know whether an updating app has any web navigation intent filters, to re-
19100             // examine handling policy even if not re-verifying.
19101             final boolean needsVerification = needsNetworkVerificationLPr(packageName);
19102             for (PackageParser.Activity a : pkg.activities) {
19103                 for (ActivityIntentInfo filter : a.intents) {
19104                     if (filter.handlesWebUris(true)) {
19105                         handlesWebUris = true;
19106                     }
19107                     if (needsVerification && filter.needsVerification()) {
19108                         if (DEBUG_DOMAIN_VERIFICATION) {
19109                             Slog.d(TAG, "autoVerify requested, processing all filters");
19110                         }
19111                         needToRunVerify = true;
19112                         // It's safe to break out here because filter.needsVerification()
19113                         // can only be true if filter.handlesWebUris(true) returned true, so
19114                         // we've already noted that.
19115                         break;
19116                     }
19117                 }
19118             }
19119 
19120             // Compare the new set of recognized hosts if the app is either requesting
19121             // autoVerify or has previously used autoVerify but no longer does.
19122             if (needToRunVerify || previouslyVerified) {
19123                 final int verificationId = mIntentFilterVerificationToken++;
19124                 for (PackageParser.Activity a : pkg.activities) {
19125                     for (ActivityIntentInfo filter : a.intents) {
19126                         // Run verification against hosts mentioned in any web-nav intent filter,
19127                         // even if the filter matches non-web schemes as well
19128                         if (filter.handlesWebUris(false /*onlyWebSchemes*/)) {
19129                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19130                                     "Verification needed for IntentFilter:" + filter.toString());
19131                             mIntentFilterVerifier.addOneIntentFilterVerification(
19132                                     verifierUid, userId, verificationId, filter, packageName);
19133                             domains.addAll(filter.getHostsList());
19134                             count++;
19135                         }
19136                     }
19137                 }
19138             }
19139 
19140             if (DEBUG_DOMAIN_VERIFICATION) {
19141                 Slog.i(TAG, "    Update published hosts: " + domains.toString());
19142             }
19143 
19144             // If we've previously verified this same host set (or a subset), we can trust that
19145             // a current ALWAYS policy is still applicable.  If this is the case, we're done.
19146             // (If we aren't in ALWAYS, we want to reverify to allow for apps that had failing
19147             // hosts in their intent filters, then pushed a new apk that removed them and now
19148             // passes.)
19149             //
19150             // Cases:
19151             //   + still autoVerify (needToRunVerify):
19152             //      - preserve current state if all of: unexpanded, in always
19153             //      - otherwise rerun as usual (fall through)
19154             //   + no longer autoVerify (alreadyVerified && !needToRunVerify)
19155             //      - wipe verification history always
19156             //      - preserve current state if all of: unexpanded, in always
19157             hostSetExpanded = !previouslyVerified
19158                     || (ivi != null && !ivi.getDomains().containsAll(domains));
19159             final int currentPolicy =
19160                     mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
19161             final boolean keepCurState = !hostSetExpanded
19162                     && currentPolicy == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
19163 
19164             if (needToRunVerify && keepCurState) {
19165                 if (DEBUG_DOMAIN_VERIFICATION) {
19166                     Slog.i(TAG, "Host set not expanding + ALWAYS -> no need to reverify");
19167                 }
19168                 ivi.setDomains(domains);
19169                 scheduleWriteSettingsLocked();
19170                 return;
19171             } else if (previouslyVerified && !needToRunVerify) {
19172                 // Prior autoVerify state but not requesting it now.  Clear autoVerify history,
19173                 // and preserve the always policy iff the host set is not expanding.
19174                 clearIntentFilterVerificationsLPw(packageName, userId, !keepCurState);
19175                 return;
19176             }
19177         }
19178 
19179         if (needToRunVerify && count > 0) {
19180             // app requested autoVerify and has at least one matching intent filter
19181             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
19182                     + " IntentFilter verification" + (count > 1 ? "s" : "")
19183                     +  " for userId:" + userId);
19184             mIntentFilterVerifier.startVerifications(userId);
19185         } else {
19186             if (DEBUG_DOMAIN_VERIFICATION) {
19187                 Slog.d(TAG, "No web filters or no new host policy for " + packageName);
19188             }
19189         }
19190      }
19191 
needsNetworkVerificationLPr(String packageName)19192     private boolean needsNetworkVerificationLPr(String packageName) {
19193         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
19194                 packageName);
19195         if (ivi == null) {
19196             return true;
19197         }
19198         int status = ivi.getStatus();
19199         switch (status) {
19200             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
19201             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
19202             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
19203                 return true;
19204 
19205             default:
19206                 // Nothing to do
19207                 return false;
19208         }
19209     }
19210 
isMultiArch(ApplicationInfo info)19211     private static boolean isMultiArch(ApplicationInfo info) {
19212         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
19213     }
19214 
isExternal(PackageParser.Package pkg)19215     private static boolean isExternal(PackageParser.Package pkg) {
19216         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
19217     }
19218 
isExternal(PackageSetting ps)19219     private static boolean isExternal(PackageSetting ps) {
19220         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
19221     }
19222 
isSystemApp(PackageParser.Package pkg)19223     private static boolean isSystemApp(PackageParser.Package pkg) {
19224         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
19225     }
19226 
isPrivilegedApp(PackageParser.Package pkg)19227     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
19228         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
19229     }
19230 
hasDomainURLs(PackageParser.Package pkg)19231     private static boolean hasDomainURLs(PackageParser.Package pkg) {
19232         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
19233     }
19234 
isSystemApp(PackageSetting ps)19235     private static boolean isSystemApp(PackageSetting ps) {
19236         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
19237     }
19238 
isUpdatedSystemApp(PackageSetting ps)19239     private static boolean isUpdatedSystemApp(PackageSetting ps) {
19240         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
19241     }
19242 
packageFlagsToInstallFlags(PackageSetting ps)19243     private int packageFlagsToInstallFlags(PackageSetting ps) {
19244         int installFlags = 0;
19245         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
19246             // This existing package was an external ASEC install when we have
19247             // the external flag without a UUID
19248             installFlags |= PackageManager.INSTALL_EXTERNAL;
19249         }
19250         if (ps.isForwardLocked()) {
19251             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
19252         }
19253         return installFlags;
19254     }
19255 
getVolumeUuidForPackage(PackageParser.Package pkg)19256     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
19257         if (isExternal(pkg)) {
19258             if (TextUtils.isEmpty(pkg.volumeUuid)) {
19259                 return StorageManager.UUID_PRIMARY_PHYSICAL;
19260             } else {
19261                 return pkg.volumeUuid;
19262             }
19263         } else {
19264             return StorageManager.UUID_PRIVATE_INTERNAL;
19265         }
19266     }
19267 
getSettingsVersionForPackage(PackageParser.Package pkg)19268     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
19269         if (isExternal(pkg)) {
19270             if (TextUtils.isEmpty(pkg.volumeUuid)) {
19271                 return mSettings.getExternalVersion();
19272             } else {
19273                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
19274             }
19275         } else {
19276             return mSettings.getInternalVersion();
19277         }
19278     }
19279 
deleteTempPackageFiles()19280     private void deleteTempPackageFiles() {
19281         final FilenameFilter filter = new FilenameFilter() {
19282             public boolean accept(File dir, String name) {
19283                 return name.startsWith("vmdl") && name.endsWith(".tmp");
19284             }
19285         };
19286         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
19287             file.delete();
19288         }
19289     }
19290 
19291     @Override
deletePackageAsUser(String packageName, int versionCode, IPackageDeleteObserver observer, int userId, int flags)19292     public void deletePackageAsUser(String packageName, int versionCode,
19293             IPackageDeleteObserver observer, int userId, int flags) {
19294         deletePackageVersioned(new VersionedPackage(packageName, versionCode),
19295                 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
19296     }
19297 
19298     @Override
deletePackageVersioned(VersionedPackage versionedPackage, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags)19299     public void deletePackageVersioned(VersionedPackage versionedPackage,
19300             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
19301         final int callingUid = Binder.getCallingUid();
19302         mContext.enforceCallingOrSelfPermission(
19303                 android.Manifest.permission.DELETE_PACKAGES, null);
19304         final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
19305         Preconditions.checkNotNull(versionedPackage);
19306         Preconditions.checkNotNull(observer);
19307         Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
19308                 PackageManager.VERSION_CODE_HIGHEST,
19309                 Integer.MAX_VALUE, "versionCode must be >= -1");
19310 
19311         final String packageName = versionedPackage.getPackageName();
19312         final int versionCode = versionedPackage.getVersionCode();
19313         final String internalPackageName;
19314         synchronized (mPackages) {
19315             // Normalize package name to handle renamed packages and static libs
19316             internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
19317                     versionedPackage.getVersionCode());
19318         }
19319 
19320         final int uid = Binder.getCallingUid();
19321         if (!isOrphaned(internalPackageName)
19322                 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
19323             try {
19324                 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
19325                 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
19326                 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
19327                 observer.onUserActionRequired(intent);
19328             } catch (RemoteException re) {
19329             }
19330             return;
19331         }
19332         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
19333         final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
19334         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
19335             mContext.enforceCallingOrSelfPermission(
19336                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
19337                     "deletePackage for user " + userId);
19338         }
19339 
19340         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
19341             try {
19342                 observer.onPackageDeleted(packageName,
19343                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
19344             } catch (RemoteException re) {
19345             }
19346             return;
19347         }
19348 
19349         if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
19350             try {
19351                 observer.onPackageDeleted(packageName,
19352                         PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
19353             } catch (RemoteException re) {
19354             }
19355             return;
19356         }
19357 
19358         if (DEBUG_REMOVE) {
19359             Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
19360                     + " deleteAllUsers: " + deleteAllUsers + " version="
19361                     + (versionCode == PackageManager.VERSION_CODE_HIGHEST
19362                     ? "VERSION_CODE_HIGHEST" : versionCode));
19363         }
19364         // Queue up an async operation since the package deletion may take a little while.
19365         mHandler.post(new Runnable() {
19366             public void run() {
19367                 mHandler.removeCallbacks(this);
19368                 int returnCode;
19369                 final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
19370                 boolean doDeletePackage = true;
19371                 if (ps != null) {
19372                     final boolean targetIsInstantApp =
19373                             ps.getInstantApp(UserHandle.getUserId(callingUid));
19374                     doDeletePackage = !targetIsInstantApp
19375                             || canViewInstantApps;
19376                 }
19377                 if (doDeletePackage) {
19378                     if (!deleteAllUsers) {
19379                         returnCode = deletePackageX(internalPackageName, versionCode,
19380                                 userId, deleteFlags);
19381                     } else {
19382                         int[] blockUninstallUserIds = getBlockUninstallForUsers(
19383                                 internalPackageName, users);
19384                         // If nobody is blocking uninstall, proceed with delete for all users
19385                         if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
19386                             returnCode = deletePackageX(internalPackageName, versionCode,
19387                                     userId, deleteFlags);
19388                         } else {
19389                             // Otherwise uninstall individually for users with blockUninstalls=false
19390                             final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
19391                             for (int userId : users) {
19392                                 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
19393                                     returnCode = deletePackageX(internalPackageName, versionCode,
19394                                             userId, userFlags);
19395                                     if (returnCode != PackageManager.DELETE_SUCCEEDED) {
19396                                         Slog.w(TAG, "Package delete failed for user " + userId
19397                                                 + ", returnCode " + returnCode);
19398                                     }
19399                                 }
19400                             }
19401                             // The app has only been marked uninstalled for certain users.
19402                             // We still need to report that delete was blocked
19403                             returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
19404                         }
19405                     }
19406                 } else {
19407                     returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19408                 }
19409                 try {
19410                     observer.onPackageDeleted(packageName, returnCode, null);
19411                 } catch (RemoteException e) {
19412                     Log.i(TAG, "Observer no longer exists.");
19413                 } //end catch
19414             } //end run
19415         });
19416     }
19417 
resolveExternalPackageNameLPr(PackageParser.Package pkg)19418     private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
19419         if (pkg.staticSharedLibName != null) {
19420             return pkg.manifestPackageName;
19421         }
19422         return pkg.packageName;
19423     }
19424 
resolveInternalPackageNameLPr(String packageName, int versionCode)19425     private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
19426         // Handle renamed packages
19427         String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
19428         packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
19429 
19430         // Is this a static library?
19431         SparseArray<SharedLibraryEntry> versionedLib =
19432                 mStaticLibsByDeclaringPackage.get(packageName);
19433         if (versionedLib == null || versionedLib.size() <= 0) {
19434             return packageName;
19435         }
19436 
19437         // Figure out which lib versions the caller can see
19438         SparseIntArray versionsCallerCanSee = null;
19439         final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
19440         if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
19441                 && callingAppId != Process.ROOT_UID) {
19442             versionsCallerCanSee = new SparseIntArray();
19443             String libName = versionedLib.valueAt(0).info.getName();
19444             String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
19445             if (uidPackages != null) {
19446                 for (String uidPackage : uidPackages) {
19447                     PackageSetting ps = mSettings.getPackageLPr(uidPackage);
19448                     final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
19449                     if (libIdx >= 0) {
19450                         final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
19451                         versionsCallerCanSee.append(libVersion, libVersion);
19452                     }
19453                 }
19454             }
19455         }
19456 
19457         // Caller can see nothing - done
19458         if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
19459             return packageName;
19460         }
19461 
19462         // Find the version the caller can see and the app version code
19463         SharedLibraryEntry highestVersion = null;
19464         final int versionCount = versionedLib.size();
19465         for (int i = 0; i < versionCount; i++) {
19466             SharedLibraryEntry libEntry = versionedLib.valueAt(i);
19467             if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
19468                     libEntry.info.getVersion()) < 0) {
19469                 continue;
19470             }
19471             final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
19472             if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
19473                 if (libVersionCode == versionCode) {
19474                     return libEntry.apk;
19475                 }
19476             } else if (highestVersion == null) {
19477                 highestVersion = libEntry;
19478             } else if (libVersionCode  > highestVersion.info
19479                     .getDeclaringPackage().getVersionCode()) {
19480                 highestVersion = libEntry;
19481             }
19482         }
19483 
19484         if (highestVersion != null) {
19485             return highestVersion.apk;
19486         }
19487 
19488         return packageName;
19489     }
19490 
isCallerVerifier(int callingUid)19491     boolean isCallerVerifier(int callingUid) {
19492         final int callingUserId = UserHandle.getUserId(callingUid);
19493         return mRequiredVerifierPackage != null &&
19494                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
19495     }
19496 
isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName)19497     private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
19498         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
19499               || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19500             return true;
19501         }
19502         final int callingUserId = UserHandle.getUserId(callingUid);
19503         // If the caller installed the pkgName, then allow it to silently uninstall.
19504         if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
19505             return true;
19506         }
19507 
19508         // Allow package verifier to silently uninstall.
19509         if (mRequiredVerifierPackage != null &&
19510                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
19511             return true;
19512         }
19513 
19514         // Allow package uninstaller to silently uninstall.
19515         if (mRequiredUninstallerPackage != null &&
19516                 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
19517             return true;
19518         }
19519 
19520         // Allow storage manager to silently uninstall.
19521         if (mStorageManagerPackage != null &&
19522                 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
19523             return true;
19524         }
19525 
19526         // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
19527         // uninstall for device owner provisioning.
19528         if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
19529                 == PERMISSION_GRANTED) {
19530             return true;
19531         }
19532 
19533         return false;
19534     }
19535 
getBlockUninstallForUsers(String packageName, int[] userIds)19536     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
19537         int[] result = EMPTY_INT_ARRAY;
19538         for (int userId : userIds) {
19539             if (getBlockUninstallForUser(packageName, userId)) {
19540                 result = ArrayUtils.appendInt(result, userId);
19541             }
19542         }
19543         return result;
19544     }
19545 
19546     @Override
isPackageDeviceAdminOnAnyUser(String packageName)19547     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
19548         final int callingUid = Binder.getCallingUid();
19549         if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
19550                 != PERMISSION_GRANTED) {
19551             EventLog.writeEvent(0x534e4554, "128599183", -1, "");
19552             throw new SecurityException(android.Manifest.permission.MANAGE_USERS
19553                     + " permission is required to call this API");
19554         }
19555         if (getInstantAppPackageName(callingUid) != null
19556                 && !isCallerSameApp(packageName, callingUid)) {
19557             return false;
19558         }
19559         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
19560     }
19561 
isPackageDeviceAdmin(String packageName, int userId)19562     private boolean isPackageDeviceAdmin(String packageName, int userId) {
19563         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
19564                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
19565         try {
19566             if (dpm != null) {
19567                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
19568                         /* callingUserOnly =*/ false);
19569                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
19570                         : deviceOwnerComponentName.getPackageName();
19571                 // Does the package contains the device owner?
19572                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
19573                 // this check is probably not needed, since DO should be registered as a device
19574                 // admin on some user too. (Original bug for this: b/17657954)
19575                 if (packageName.equals(deviceOwnerPackageName)) {
19576                     return true;
19577                 }
19578                 // Does it contain a device admin for any user?
19579                 int[] users;
19580                 if (userId == UserHandle.USER_ALL) {
19581                     users = sUserManager.getUserIds();
19582                 } else {
19583                     users = new int[]{userId};
19584                 }
19585                 for (int i = 0; i < users.length; ++i) {
19586                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
19587                         return true;
19588                     }
19589                 }
19590             }
19591         } catch (RemoteException e) {
19592         }
19593         return false;
19594     }
19595 
shouldKeepUninstalledPackageLPr(String packageName)19596     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
19597         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
19598     }
19599 
19600     /**
19601      *  This method is an internal method that could be get invoked either
19602      *  to delete an installed package or to clean up a failed installation.
19603      *  After deleting an installed package, a broadcast is sent to notify any
19604      *  listeners that the package has been removed. For cleaning up a failed
19605      *  installation, the broadcast is not necessary since the package's
19606      *  installation wouldn't have sent the initial broadcast either
19607      *  The key steps in deleting a package are
19608      *  deleting the package information in internal structures like mPackages,
19609      *  deleting the packages base directories through installd
19610      *  updating mSettings to reflect current status
19611      *  persisting settings for later use
19612      *  sending a broadcast if necessary
19613      */
deletePackageX(String packageName, int versionCode, int userId, int deleteFlags)19614     int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
19615         final PackageRemovedInfo info = new PackageRemovedInfo(this);
19616         final boolean res;
19617 
19618         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
19619                 ? UserHandle.USER_ALL : userId;
19620 
19621         if (isPackageDeviceAdmin(packageName, removeUser)) {
19622             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
19623             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
19624         }
19625 
19626         PackageSetting uninstalledPs = null;
19627         PackageParser.Package pkg = null;
19628 
19629         // for the uninstall-updates case and restricted profiles, remember the per-
19630         // user handle installed state
19631         int[] allUsers;
19632         synchronized (mPackages) {
19633             uninstalledPs = mSettings.mPackages.get(packageName);
19634             if (uninstalledPs == null) {
19635                 Slog.w(TAG, "Not removing non-existent package " + packageName);
19636                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19637             }
19638 
19639             if (versionCode != PackageManager.VERSION_CODE_HIGHEST
19640                     && uninstalledPs.versionCode != versionCode) {
19641                 Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
19642                         + uninstalledPs.versionCode + " != " + versionCode);
19643                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19644             }
19645 
19646             // Static shared libs can be declared by any package, so let us not
19647             // allow removing a package if it provides a lib others depend on.
19648             pkg = mPackages.get(packageName);
19649 
19650             allUsers = sUserManager.getUserIds();
19651 
19652             if (pkg != null && pkg.staticSharedLibName != null) {
19653                 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
19654                         pkg.staticSharedLibVersion);
19655                 if (libEntry != null) {
19656                     for (int currUserId : allUsers) {
19657                         if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
19658                             continue;
19659                         }
19660                         List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
19661                                 libEntry.info, MATCH_KNOWN_PACKAGES, currUserId);
19662                         if (!ArrayUtils.isEmpty(libClientPackages)) {
19663                             Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
19664                                     + " hosting lib " + libEntry.info.getName() + " version "
19665                                     + libEntry.info.getVersion() + " used by " + libClientPackages
19666                                     + " for user " + currUserId);
19667                             return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
19668                         }
19669                     }
19670                 }
19671             }
19672 
19673             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
19674         }
19675 
19676         final int freezeUser;
19677         if (isUpdatedSystemApp(uninstalledPs)
19678                 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
19679             // We're downgrading a system app, which will apply to all users, so
19680             // freeze them all during the downgrade
19681             freezeUser = UserHandle.USER_ALL;
19682         } else {
19683             freezeUser = removeUser;
19684         }
19685 
19686         synchronized (mInstallLock) {
19687             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
19688             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
19689                     deleteFlags, "deletePackageX")) {
19690                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
19691                         deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
19692             }
19693             synchronized (mPackages) {
19694                 if (res) {
19695                     if (pkg != null) {
19696                         mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
19697                     }
19698                     updateSequenceNumberLP(uninstalledPs, info.removedUsers);
19699                     updateInstantAppInstallerLocked(packageName);
19700                 }
19701             }
19702         }
19703 
19704         if (res) {
19705             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
19706             info.sendPackageRemovedBroadcasts(killApp);
19707             info.sendSystemPackageUpdatedBroadcasts();
19708             info.sendSystemPackageAppearedBroadcasts();
19709         }
19710         // Force a gc here.
19711         Runtime.getRuntime().gc();
19712         // Delete the resources here after sending the broadcast to let
19713         // other processes clean up before deleting resources.
19714         if (info.args != null) {
19715             synchronized (mInstallLock) {
19716                 info.args.doPostDeleteLI(true);
19717             }
19718         }
19719 
19720         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19721     }
19722 
19723     static class PackageRemovedInfo {
19724         final PackageSender packageSender;
19725         String removedPackage;
19726         String installerPackageName;
19727         int uid = -1;
19728         int removedAppId = -1;
19729         int[] origUsers;
19730         int[] removedUsers = null;
19731         int[] broadcastUsers = null;
19732         SparseArray<Integer> installReasons;
19733         boolean isRemovedPackageSystemUpdate = false;
19734         boolean isUpdate;
19735         boolean dataRemoved;
19736         boolean removedForAllUsers;
19737         boolean isStaticSharedLib;
19738         // Clean up resources deleted packages.
19739         InstallArgs args = null;
19740         ArrayMap<String, PackageRemovedInfo> removedChildPackages;
19741         ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
19742 
PackageRemovedInfo(PackageSender packageSender)19743         PackageRemovedInfo(PackageSender packageSender) {
19744             this.packageSender = packageSender;
19745         }
19746 
sendPackageRemovedBroadcasts(boolean killApp)19747         void sendPackageRemovedBroadcasts(boolean killApp) {
19748             sendPackageRemovedBroadcastInternal(killApp);
19749             final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
19750             for (int i = 0; i < childCount; i++) {
19751                 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19752                 childInfo.sendPackageRemovedBroadcastInternal(killApp);
19753             }
19754         }
19755 
sendSystemPackageUpdatedBroadcasts()19756         void sendSystemPackageUpdatedBroadcasts() {
19757             if (isRemovedPackageSystemUpdate) {
19758                 sendSystemPackageUpdatedBroadcastsInternal();
19759                 final int childCount = (removedChildPackages != null)
19760                         ? removedChildPackages.size() : 0;
19761                 for (int i = 0; i < childCount; i++) {
19762                     PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19763                     if (childInfo.isRemovedPackageSystemUpdate) {
19764                         childInfo.sendSystemPackageUpdatedBroadcastsInternal();
19765                     }
19766                 }
19767             }
19768         }
19769 
sendSystemPackageAppearedBroadcasts()19770         void sendSystemPackageAppearedBroadcasts() {
19771             final int packageCount = (appearedChildPackages != null)
19772                     ? appearedChildPackages.size() : 0;
19773             for (int i = 0; i < packageCount; i++) {
19774                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
19775                 packageSender.sendPackageAddedForNewUsers(installedInfo.name,
19776                     true /*sendBootCompleted*/, false /*startReceiver*/,
19777                     UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
19778             }
19779         }
19780 
sendSystemPackageUpdatedBroadcastsInternal()19781         private void sendSystemPackageUpdatedBroadcastsInternal() {
19782             Bundle extras = new Bundle(2);
19783             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19784             extras.putBoolean(Intent.EXTRA_REPLACING, true);
19785             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19786                 removedPackage, extras, 0, null /*targetPackage*/, null, null);
19787             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19788                 removedPackage, extras, 0, null /*targetPackage*/, null, null);
19789             packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
19790                 null, null, 0, removedPackage, null, null);
19791             if (installerPackageName != null) {
19792                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19793                         removedPackage, extras, 0 /*flags*/,
19794                         installerPackageName, null, null);
19795                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19796                         removedPackage, extras, 0 /*flags*/,
19797                         installerPackageName, null, null);
19798             }
19799         }
19800 
sendPackageRemovedBroadcastInternal(boolean killApp)19801         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
19802             // Don't send static shared library removal broadcasts as these
19803             // libs are visible only the the apps that depend on them an one
19804             // cannot remove the library if it has a dependency.
19805             if (isStaticSharedLib) {
19806                 return;
19807             }
19808             Bundle extras = new Bundle(2);
19809             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
19810             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
19811             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
19812             if (isUpdate || isRemovedPackageSystemUpdate) {
19813                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
19814             }
19815             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
19816             if (removedPackage != null) {
19817                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19818                     removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
19819                 if (installerPackageName != null) {
19820                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19821                             removedPackage, extras, 0 /*flags*/,
19822                             installerPackageName, null, broadcastUsers);
19823                 }
19824                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
19825                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
19826                         removedPackage, extras,
19827                         Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19828                         null, null, broadcastUsers);
19829                 }
19830             }
19831             if (removedAppId >= 0) {
19832                 packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
19833                     null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19834                     null, null, broadcastUsers);
19835             }
19836         }
19837 
populateUsers(int[] userIds, PackageSetting deletedPackageSetting)19838         void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
19839             removedUsers = userIds;
19840             if (removedUsers == null) {
19841                 broadcastUsers = null;
19842                 return;
19843             }
19844 
19845             broadcastUsers = EMPTY_INT_ARRAY;
19846             for (int i = userIds.length - 1; i >= 0; --i) {
19847                 final int userId = userIds[i];
19848                 if (deletedPackageSetting.getInstantApp(userId)) {
19849                     continue;
19850                 }
19851                 broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
19852             }
19853         }
19854     }
19855 
19856     /*
19857      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
19858      * flag is not set, the data directory is removed as well.
19859      * make sure this flag is set for partially installed apps. If not its meaningless to
19860      * delete a partially installed application.
19861      */
removePackageDataLIF(PackageSetting ps, int[] allUserHandles, PackageRemovedInfo outInfo, int flags, boolean writeSettings)19862     private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
19863             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
19864         String packageName = ps.name;
19865         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19866         // Retrieve object to delete permissions for shared user later on
19867         final PackageParser.Package deletedPkg;
19868         final PackageSetting deletedPs;
19869         // reader
19870         synchronized (mPackages) {
19871             deletedPkg = mPackages.get(packageName);
19872             deletedPs = mSettings.mPackages.get(packageName);
19873             if (outInfo != null) {
19874                 outInfo.removedPackage = packageName;
19875                 outInfo.installerPackageName = ps.installerPackageName;
19876                 outInfo.isStaticSharedLib = deletedPkg != null
19877                         && deletedPkg.staticSharedLibName != null;
19878                 outInfo.populateUsers(deletedPs == null ? null
19879                         : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19880             }
19881         }
19882 
19883         removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19884 
19885         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19886             final PackageParser.Package resolvedPkg;
19887             if (deletedPkg != null) {
19888                 resolvedPkg = deletedPkg;
19889             } else {
19890                 // We don't have a parsed package when it lives on an ejected
19891                 // adopted storage device, so fake something together
19892                 resolvedPkg = new PackageParser.Package(ps.name);
19893                 resolvedPkg.setVolumeUuid(ps.volumeUuid);
19894             }
19895             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19896                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19897             destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19898             if (outInfo != null) {
19899                 outInfo.dataRemoved = true;
19900             }
19901             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19902         }
19903 
19904         int removedAppId = -1;
19905 
19906         // writer
19907         synchronized (mPackages) {
19908             boolean installedStateChanged = false;
19909             if (deletedPs != null) {
19910                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19911                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true);
19912                     clearDefaultBrowserIfNeeded(packageName);
19913                     mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19914                     removedAppId = mSettings.removePackageLPw(packageName);
19915                     if (outInfo != null) {
19916                         outInfo.removedAppId = removedAppId;
19917                     }
19918                     updatePermissionsLPw(deletedPs.name, null, 0);
19919                     if (deletedPs.sharedUser != null) {
19920                         // Remove permissions associated with package. Since runtime
19921                         // permissions are per user we have to kill the removed package
19922                         // or packages running under the shared user of the removed
19923                         // package if revoking the permissions requested only by the removed
19924                         // package is successful and this causes a change in gids.
19925                         for (int userId : UserManagerService.getInstance().getUserIds()) {
19926                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19927                                     userId);
19928                             if (userIdToKill == UserHandle.USER_ALL
19929                                     || userIdToKill >= UserHandle.USER_SYSTEM) {
19930                                 // If gids changed for this user, kill all affected packages.
19931                                 mHandler.post(new Runnable() {
19932                                     @Override
19933                                     public void run() {
19934                                         // This has to happen with no lock held.
19935                                         killApplication(deletedPs.name, deletedPs.appId,
19936                                                 KILL_APP_REASON_GIDS_CHANGED);
19937                                     }
19938                                 });
19939                                 break;
19940                             }
19941                         }
19942                     }
19943                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19944                 }
19945                 // make sure to preserve per-user disabled state if this removal was just
19946                 // a downgrade of a system app to the factory package
19947                 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19948                     if (DEBUG_REMOVE) {
19949                         Slog.d(TAG, "Propagating install state across downgrade");
19950                     }
19951                     for (int userId : allUserHandles) {
19952                         final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19953                         if (DEBUG_REMOVE) {
19954                             Slog.d(TAG, "    user " + userId + " => " + installed);
19955                         }
19956                         if (installed != ps.getInstalled(userId)) {
19957                             installedStateChanged = true;
19958                         }
19959                         ps.setInstalled(installed, userId);
19960                     }
19961                 }
19962             }
19963             // can downgrade to reader
19964             if (writeSettings) {
19965                 // Save settings now
19966                 mSettings.writeLPr();
19967             }
19968             if (installedStateChanged) {
19969                 mSettings.writeKernelMappingLPr(ps);
19970             }
19971         }
19972         if (removedAppId != -1) {
19973             // A user ID was deleted here. Go through all users and remove it
19974             // from KeyStore.
19975             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19976         }
19977     }
19978 
locationIsPrivileged(File path)19979     static boolean locationIsPrivileged(File path) {
19980         try {
19981             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19982                     .getCanonicalPath();
19983             return path.getCanonicalPath().startsWith(privilegedAppDir);
19984         } catch (IOException e) {
19985             Slog.e(TAG, "Unable to access code path " + path);
19986         }
19987         return false;
19988     }
19989 
19990     /*
19991      * Tries to delete system package.
19992      */
deleteSystemPackageLIF(PackageParser.Package deletedPkg, PackageSetting deletedPs, int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo, boolean writeSettings)19993     private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19994             PackageSetting deletedPs, int[] allUserHandles, int flags,
19995             @Nullable PackageRemovedInfo outInfo,
19996             boolean writeSettings) {
19997         if (deletedPs.parentPackageName != null) {
19998             Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19999             return false;
20000         }
20001 
20002         final boolean applyUserRestrictions
20003                 = (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
20004         final PackageSetting disabledPs;
20005         // Confirm if the system package has been updated
20006         // An updated system app can be deleted. This will also have to restore
20007         // the system pkg from system partition
20008         // reader
20009         synchronized (mPackages) {
20010             disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
20011         }
20012 
20013         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
20014                 + " disabledPs=" + disabledPs);
20015 
20016         if (disabledPs == null) {
20017             Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
20018             return false;
20019         } else if (DEBUG_REMOVE) {
20020             Slog.d(TAG, "Deleting system pkg from data partition");
20021         }
20022 
20023         if (DEBUG_REMOVE) {
20024             if (applyUserRestrictions) {
20025                 Slog.d(TAG, "Remembering install states:");
20026                 for (int userId : allUserHandles) {
20027                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
20028                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
20029                 }
20030             }
20031         }
20032 
20033         if (outInfo != null) {
20034             // Delete the updated package
20035             outInfo.isRemovedPackageSystemUpdate = true;
20036             if (outInfo.removedChildPackages != null) {
20037                 final int childCount = (deletedPs.childPackageNames != null)
20038                         ? deletedPs.childPackageNames.size() : 0;
20039                 for (int i = 0; i < childCount; i++) {
20040                     String childPackageName = deletedPs.childPackageNames.get(i);
20041                     if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
20042                             .contains(childPackageName)) {
20043                         PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
20044                                 childPackageName);
20045                         if (childInfo != null) {
20046                             childInfo.isRemovedPackageSystemUpdate = true;
20047                         }
20048                     }
20049                 }
20050             }
20051         }
20052 
20053         if (disabledPs.versionCode < deletedPs.versionCode) {
20054             // Delete data for downgrades
20055             flags &= ~PackageManager.DELETE_KEEP_DATA;
20056         } else {
20057             // Preserve data by setting flag
20058             flags |= PackageManager.DELETE_KEEP_DATA;
20059         }
20060 
20061         boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
20062                 outInfo, writeSettings, disabledPs.pkg);
20063         if (!ret) {
20064             return false;
20065         }
20066 
20067         // writer
20068         synchronized (mPackages) {
20069             // NOTE: The system package always needs to be enabled; even if it's for
20070             // a compressed stub. If we don't, installing the system package fails
20071             // during scan [scanning checks the disabled packages]. We will reverse
20072             // this later, after we've "installed" the stub.
20073             // Reinstate the old system package
20074             enableSystemPackageLPw(disabledPs.pkg);
20075             // Remove any native libraries from the upgraded package.
20076             removeNativeBinariesLI(deletedPs);
20077         }
20078 
20079         // Install the system package
20080         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
20081         try {
20082             installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles,
20083                     outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
20084         } catch (PackageManagerException e) {
20085             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
20086                     + e.getMessage());
20087             return false;
20088         } finally {
20089             if (disabledPs.pkg.isStub) {
20090                 mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
20091             }
20092         }
20093         return true;
20094     }
20095 
20096     /**
20097      * Installs a package that's already on the system partition.
20098      */
installPackageFromSystemLIF(@onNull File codePath, boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles, @Nullable PermissionsState origPermissionState, boolean writeSettings)20099     private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath,
20100             boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
20101             @Nullable PermissionsState origPermissionState, boolean writeSettings)
20102                     throws PackageManagerException {
20103         int parseFlags = mDefParseFlags
20104                 | PackageParser.PARSE_MUST_BE_APK
20105                 | PackageParser.PARSE_IS_SYSTEM
20106                 | PackageParser.PARSE_IS_SYSTEM_DIR;
20107         if (isPrivileged || locationIsPrivileged(codePath)) {
20108             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
20109         }
20110 
20111         final PackageParser.Package newPkg =
20112                 scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null);
20113 
20114         try {
20115             // update shared libraries for the newly re-installed system package
20116             updateSharedLibrariesLPr(newPkg, null);
20117         } catch (PackageManagerException e) {
20118             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
20119         }
20120 
20121         prepareAppDataAfterInstallLIF(newPkg);
20122 
20123         // writer
20124         synchronized (mPackages) {
20125             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
20126 
20127             // Propagate the permissions state as we do not want to drop on the floor
20128             // runtime permissions. The update permissions method below will take
20129             // care of removing obsolete permissions and grant install permissions.
20130             if (origPermissionState != null) {
20131                 ps.getPermissionsState().copyFrom(origPermissionState);
20132             }
20133             updatePermissionsLPw(newPkg.packageName, newPkg,
20134                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
20135 
20136             final boolean applyUserRestrictions
20137                     = (allUserHandles != null) && (origUserHandles != null);
20138             if (applyUserRestrictions) {
20139                 boolean installedStateChanged = false;
20140                 if (DEBUG_REMOVE) {
20141                     Slog.d(TAG, "Propagating install state across reinstall");
20142                 }
20143                 for (int userId : allUserHandles) {
20144                     final boolean installed = ArrayUtils.contains(origUserHandles, userId);
20145                     if (DEBUG_REMOVE) {
20146                         Slog.d(TAG, "    user " + userId + " => " + installed);
20147                     }
20148                     if (installed != ps.getInstalled(userId)) {
20149                         installedStateChanged = true;
20150                     }
20151                     ps.setInstalled(installed, userId);
20152 
20153                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20154                 }
20155                 // Regardless of writeSettings we need to ensure that this restriction
20156                 // state propagation is persisted
20157                 mSettings.writeAllUsersPackageRestrictionsLPr();
20158                 if (installedStateChanged) {
20159                     mSettings.writeKernelMappingLPr(ps);
20160                 }
20161             }
20162             // can downgrade to reader here
20163             if (writeSettings) {
20164                 mSettings.writeLPr();
20165             }
20166         }
20167         return newPkg;
20168     }
20169 
deleteInstalledPackageLIF(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, PackageRemovedInfo outInfo, boolean writeSettings, PackageParser.Package replacingPackage)20170     private boolean deleteInstalledPackageLIF(PackageSetting ps,
20171             boolean deleteCodeAndResources, int flags, int[] allUserHandles,
20172             PackageRemovedInfo outInfo, boolean writeSettings,
20173             PackageParser.Package replacingPackage) {
20174         synchronized (mPackages) {
20175             if (outInfo != null) {
20176                 outInfo.uid = ps.appId;
20177             }
20178 
20179             if (outInfo != null && outInfo.removedChildPackages != null) {
20180                 final int childCount = (ps.childPackageNames != null)
20181                         ? ps.childPackageNames.size() : 0;
20182                 for (int i = 0; i < childCount; i++) {
20183                     String childPackageName = ps.childPackageNames.get(i);
20184                     PackageSetting childPs = mSettings.mPackages.get(childPackageName);
20185                     if (childPs == null) {
20186                         return false;
20187                     }
20188                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
20189                             childPackageName);
20190                     if (childInfo != null) {
20191                         childInfo.uid = childPs.appId;
20192                     }
20193                 }
20194             }
20195         }
20196 
20197         // Delete package data from internal structures and also remove data if flag is set
20198         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
20199 
20200         // Delete the child packages data
20201         final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
20202         for (int i = 0; i < childCount; i++) {
20203             PackageSetting childPs;
20204             synchronized (mPackages) {
20205                 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
20206             }
20207             if (childPs != null) {
20208                 PackageRemovedInfo childOutInfo = (outInfo != null
20209                         && outInfo.removedChildPackages != null)
20210                         ? outInfo.removedChildPackages.get(childPs.name) : null;
20211                 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
20212                         && (replacingPackage != null
20213                         && !replacingPackage.hasChildPackage(childPs.name))
20214                         ? flags & ~DELETE_KEEP_DATA : flags;
20215                 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
20216                         deleteFlags, writeSettings);
20217             }
20218         }
20219 
20220         // Delete application code and resources only for parent packages
20221         if (ps.parentPackageName == null) {
20222             if (deleteCodeAndResources && (outInfo != null)) {
20223                 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
20224                         ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
20225                 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
20226             }
20227         }
20228 
20229         return true;
20230     }
20231 
20232     @Override
setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)20233     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
20234             int userId) {
20235         mContext.enforceCallingOrSelfPermission(
20236                 android.Manifest.permission.DELETE_PACKAGES, null);
20237         synchronized (mPackages) {
20238             // Cannot block uninstall of static shared libs as they are
20239             // considered a part of the using app (emulating static linking).
20240             // Also static libs are installed always on internal storage.
20241             PackageParser.Package pkg = mPackages.get(packageName);
20242             if (pkg != null && pkg.staticSharedLibName != null) {
20243                 Slog.w(TAG, "Cannot block uninstall of package: " + packageName
20244                         + " providing static shared library: " + pkg.staticSharedLibName);
20245                 return false;
20246             }
20247             mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
20248             mSettings.writePackageRestrictionsLPr(userId);
20249         }
20250         return true;
20251     }
20252 
20253     @Override
getBlockUninstallForUser(String packageName, int userId)20254     public boolean getBlockUninstallForUser(String packageName, int userId) {
20255         synchronized (mPackages) {
20256             final PackageSetting ps = mSettings.mPackages.get(packageName);
20257             if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
20258                 return false;
20259             }
20260             return mSettings.getBlockUninstallLPr(userId, packageName);
20261         }
20262     }
20263 
20264     @Override
setRequiredForSystemUser(String packageName, boolean systemUserApp)20265     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
20266         enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
20267         synchronized (mPackages) {
20268             PackageSetting ps = mSettings.mPackages.get(packageName);
20269             if (ps == null) {
20270                 Log.w(TAG, "Package doesn't exist: " + packageName);
20271                 return false;
20272             }
20273             if (systemUserApp) {
20274                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20275             } else {
20276                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20277             }
20278             mSettings.writeLPr();
20279         }
20280         return true;
20281     }
20282 
20283     /*
20284      * This method handles package deletion in general
20285      */
deletePackageLIF(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings, PackageParser.Package replacingPackage)20286     private boolean deletePackageLIF(String packageName, UserHandle user,
20287             boolean deleteCodeAndResources, int[] allUserHandles, int flags,
20288             PackageRemovedInfo outInfo, boolean writeSettings,
20289             PackageParser.Package replacingPackage) {
20290         if (packageName == null) {
20291             Slog.w(TAG, "Attempt to delete null packageName.");
20292             return false;
20293         }
20294 
20295         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
20296 
20297         PackageSetting ps;
20298         synchronized (mPackages) {
20299             ps = mSettings.mPackages.get(packageName);
20300             if (ps == null) {
20301                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20302                 return false;
20303             }
20304 
20305             if (ps.parentPackageName != null && (!isSystemApp(ps)
20306                     || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
20307                 if (DEBUG_REMOVE) {
20308                     Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
20309                             + ((user == null) ? UserHandle.USER_ALL : user));
20310                 }
20311                 final int removedUserId = (user != null) ? user.getIdentifier()
20312                         : UserHandle.USER_ALL;
20313                 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
20314                     return false;
20315                 }
20316                 markPackageUninstalledForUserLPw(ps, user);
20317                 scheduleWritePackageRestrictionsLocked(user);
20318                 return true;
20319             }
20320         }
20321 
20322         if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
20323                 && user.getIdentifier() != UserHandle.USER_ALL)) {
20324             // The caller is asking that the package only be deleted for a single
20325             // user.  To do this, we just mark its uninstalled state and delete
20326             // its data. If this is a system app, we only allow this to happen if
20327             // they have set the special DELETE_SYSTEM_APP which requests different
20328             // semantics than normal for uninstalling system apps.
20329             markPackageUninstalledForUserLPw(ps, user);
20330 
20331             if (!isSystemApp(ps)) {
20332                 // Do not uninstall the APK if an app should be cached
20333                 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
20334                 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
20335                     // Other user still have this package installed, so all
20336                     // we need to do is clear this user's data and save that
20337                     // it is uninstalled.
20338                     if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
20339                     if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20340                         return false;
20341                     }
20342                     scheduleWritePackageRestrictionsLocked(user);
20343                     return true;
20344                 } else {
20345                     // We need to set it back to 'installed' so the uninstall
20346                     // broadcasts will be sent correctly.
20347                     if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
20348                     ps.setInstalled(true, user.getIdentifier());
20349                     mSettings.writeKernelMappingLPr(ps);
20350                 }
20351             } else {
20352                 // This is a system app, so we assume that the
20353                 // other users still have this package installed, so all
20354                 // we need to do is clear this user's data and save that
20355                 // it is uninstalled.
20356                 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
20357                 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20358                     return false;
20359                 }
20360                 scheduleWritePackageRestrictionsLocked(user);
20361                 return true;
20362             }
20363         }
20364 
20365         // If we are deleting a composite package for all users, keep track
20366         // of result for each child.
20367         if (ps.childPackageNames != null && outInfo != null) {
20368             synchronized (mPackages) {
20369                 final int childCount = ps.childPackageNames.size();
20370                 outInfo.removedChildPackages = new ArrayMap<>(childCount);
20371                 for (int i = 0; i < childCount; i++) {
20372                     String childPackageName = ps.childPackageNames.get(i);
20373                     PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
20374                     childInfo.removedPackage = childPackageName;
20375                     childInfo.installerPackageName = ps.installerPackageName;
20376                     outInfo.removedChildPackages.put(childPackageName, childInfo);
20377                     PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20378                     if (childPs != null) {
20379                         childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
20380                     }
20381                 }
20382             }
20383         }
20384 
20385         boolean ret = false;
20386         if (isSystemApp(ps)) {
20387             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
20388             // When an updated system application is deleted we delete the existing resources
20389             // as well and fall back to existing code in system partition
20390             ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
20391         } else {
20392             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
20393             ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
20394                     outInfo, writeSettings, replacingPackage);
20395         }
20396 
20397         // Take a note whether we deleted the package for all users
20398         if (outInfo != null) {
20399             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
20400             if (outInfo.removedChildPackages != null) {
20401                 synchronized (mPackages) {
20402                     final int childCount = outInfo.removedChildPackages.size();
20403                     for (int i = 0; i < childCount; i++) {
20404                         PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
20405                         if (childInfo != null) {
20406                             childInfo.removedForAllUsers = mPackages.get(
20407                                     childInfo.removedPackage) == null;
20408                         }
20409                     }
20410                 }
20411             }
20412             // If we uninstalled an update to a system app there may be some
20413             // child packages that appeared as they are declared in the system
20414             // app but were not declared in the update.
20415             if (isSystemApp(ps)) {
20416                 synchronized (mPackages) {
20417                     PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
20418                     final int childCount = (updatedPs.childPackageNames != null)
20419                             ? updatedPs.childPackageNames.size() : 0;
20420                     for (int i = 0; i < childCount; i++) {
20421                         String childPackageName = updatedPs.childPackageNames.get(i);
20422                         if (outInfo.removedChildPackages == null
20423                                 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
20424                             PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20425                             if (childPs == null) {
20426                                 continue;
20427                             }
20428                             PackageInstalledInfo installRes = new PackageInstalledInfo();
20429                             installRes.name = childPackageName;
20430                             installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
20431                             installRes.pkg = mPackages.get(childPackageName);
20432                             installRes.uid = childPs.pkg.applicationInfo.uid;
20433                             if (outInfo.appearedChildPackages == null) {
20434                                 outInfo.appearedChildPackages = new ArrayMap<>();
20435                             }
20436                             outInfo.appearedChildPackages.put(childPackageName, installRes);
20437                         }
20438                     }
20439                 }
20440             }
20441         }
20442 
20443         return ret;
20444     }
20445 
markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user)20446     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
20447         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
20448                 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
20449         for (int nextUserId : userIds) {
20450             if (DEBUG_REMOVE) {
20451                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
20452             }
20453             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
20454                     false /*installed*/,
20455                     true /*stopped*/,
20456                     true /*notLaunched*/,
20457                     false /*hidden*/,
20458                     false /*suspended*/,
20459                     false /*instantApp*/,
20460                     false /*virtualPreload*/,
20461                     null /*lastDisableAppCaller*/,
20462                     null /*enabledComponents*/,
20463                     null /*disabledComponents*/,
20464                     ps.readUserState(nextUserId).domainVerificationStatus,
20465                     0, PackageManager.INSTALL_REASON_UNKNOWN);
20466         }
20467         mSettings.writeKernelMappingLPr(ps);
20468     }
20469 
clearPackageStateForUserLIF(PackageSetting ps, int userId, PackageRemovedInfo outInfo)20470     private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
20471             PackageRemovedInfo outInfo) {
20472         final PackageParser.Package pkg;
20473         synchronized (mPackages) {
20474             pkg = mPackages.get(ps.name);
20475         }
20476 
20477         final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
20478                 : new int[] {userId};
20479         for (int nextUserId : userIds) {
20480             if (DEBUG_REMOVE) {
20481                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
20482                         + nextUserId);
20483             }
20484 
20485             destroyAppDataLIF(pkg, userId,
20486                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20487             destroyAppProfilesLIF(pkg, userId);
20488             clearDefaultBrowserIfNeededForUser(ps.name, userId);
20489             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
20490             schedulePackageCleaning(ps.name, nextUserId, false);
20491             synchronized (mPackages) {
20492                 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
20493                     scheduleWritePackageRestrictionsLocked(nextUserId);
20494                 }
20495                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
20496             }
20497         }
20498 
20499         if (outInfo != null) {
20500             outInfo.removedPackage = ps.name;
20501             outInfo.installerPackageName = ps.installerPackageName;
20502             outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
20503             outInfo.removedAppId = ps.appId;
20504             outInfo.removedUsers = userIds;
20505             outInfo.broadcastUsers = userIds;
20506         }
20507 
20508         return true;
20509     }
20510 
20511     private final class ClearStorageConnection implements ServiceConnection {
20512         IMediaContainerService mContainerService;
20513 
20514         @Override
onServiceConnected(ComponentName name, IBinder service)20515         public void onServiceConnected(ComponentName name, IBinder service) {
20516             synchronized (this) {
20517                 mContainerService = IMediaContainerService.Stub
20518                         .asInterface(Binder.allowBlocking(service));
20519                 notifyAll();
20520             }
20521         }
20522 
20523         @Override
onServiceDisconnected(ComponentName name)20524         public void onServiceDisconnected(ComponentName name) {
20525         }
20526     }
20527 
clearExternalStorageDataSync(String packageName, int userId, boolean allData)20528     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
20529         if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
20530 
20531         final boolean mounted;
20532         if (Environment.isExternalStorageEmulated()) {
20533             mounted = true;
20534         } else {
20535             final String status = Environment.getExternalStorageState();
20536 
20537             mounted = status.equals(Environment.MEDIA_MOUNTED)
20538                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
20539         }
20540 
20541         if (!mounted) {
20542             return;
20543         }
20544 
20545         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
20546         int[] users;
20547         if (userId == UserHandle.USER_ALL) {
20548             users = sUserManager.getUserIds();
20549         } else {
20550             users = new int[] { userId };
20551         }
20552         final ClearStorageConnection conn = new ClearStorageConnection();
20553         if (mContext.bindServiceAsUser(
20554                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
20555             try {
20556                 for (int curUser : users) {
20557                     long timeout = SystemClock.uptimeMillis() + 5000;
20558                     synchronized (conn) {
20559                         long now;
20560                         while (conn.mContainerService == null &&
20561                                 (now = SystemClock.uptimeMillis()) < timeout) {
20562                             try {
20563                                 conn.wait(timeout - now);
20564                             } catch (InterruptedException e) {
20565                             }
20566                         }
20567                     }
20568                     if (conn.mContainerService == null) {
20569                         return;
20570                     }
20571 
20572                     final UserEnvironment userEnv = new UserEnvironment(curUser);
20573                     clearDirectory(conn.mContainerService,
20574                             userEnv.buildExternalStorageAppCacheDirs(packageName));
20575                     if (allData) {
20576                         clearDirectory(conn.mContainerService,
20577                                 userEnv.buildExternalStorageAppDataDirs(packageName));
20578                         clearDirectory(conn.mContainerService,
20579                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
20580                     }
20581                 }
20582             } finally {
20583                 mContext.unbindService(conn);
20584             }
20585         }
20586     }
20587 
20588     @Override
clearApplicationProfileData(String packageName)20589     public void clearApplicationProfileData(String packageName) {
20590         enforceSystemOrRoot("Only the system can clear all profile data");
20591 
20592         final PackageParser.Package pkg;
20593         synchronized (mPackages) {
20594             pkg = mPackages.get(packageName);
20595         }
20596 
20597         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
20598             synchronized (mInstallLock) {
20599                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20600             }
20601         }
20602     }
20603 
20604     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)20605     public void clearApplicationUserData(final String packageName,
20606             final IPackageDataObserver observer, final int userId) {
20607         mContext.enforceCallingOrSelfPermission(
20608                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
20609 
20610         final int callingUid = Binder.getCallingUid();
20611         enforceCrossUserPermission(callingUid, userId,
20612                 true /* requireFullPermission */, false /* checkShell */, "clear application data");
20613 
20614         final PackageSetting ps = mSettings.getPackageLPr(packageName);
20615         final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
20616         if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
20617             throw new SecurityException("Cannot clear data for a protected package: "
20618                     + packageName);
20619         }
20620         // Queue up an async operation since the package deletion may take a little while.
20621         mHandler.post(new Runnable() {
20622             public void run() {
20623                 mHandler.removeCallbacks(this);
20624                 final boolean succeeded;
20625                 if (!filterApp) {
20626                     try (PackageFreezer freezer = freezePackage(packageName,
20627                             "clearApplicationUserData")) {
20628                         synchronized (mInstallLock) {
20629                             succeeded = clearApplicationUserDataLIF(packageName, userId);
20630                         }
20631                         clearExternalStorageDataSync(packageName, userId, true);
20632                         synchronized (mPackages) {
20633                             mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
20634                                     packageName, userId);
20635                         }
20636                     }
20637                     if (succeeded) {
20638                         // invoke DeviceStorageMonitor's update method to clear any notifications
20639                         DeviceStorageMonitorInternal dsm = LocalServices
20640                                 .getService(DeviceStorageMonitorInternal.class);
20641                         if (dsm != null) {
20642                             dsm.checkMemory();
20643                         }
20644                     }
20645                 } else {
20646                     succeeded = false;
20647                 }
20648                 if (observer != null) {
20649                     try {
20650                         observer.onRemoveCompleted(packageName, succeeded);
20651                     } catch (RemoteException e) {
20652                         Log.i(TAG, "Observer no longer exists.");
20653                     }
20654                 } //end if observer
20655             } //end run
20656         });
20657     }
20658 
clearApplicationUserDataLIF(String packageName, int userId)20659     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
20660         if (packageName == null) {
20661             Slog.w(TAG, "Attempt to delete null packageName.");
20662             return false;
20663         }
20664 
20665         // Try finding details about the requested package
20666         PackageParser.Package pkg;
20667         synchronized (mPackages) {
20668             pkg = mPackages.get(packageName);
20669             if (pkg == null) {
20670                 final PackageSetting ps = mSettings.mPackages.get(packageName);
20671                 if (ps != null) {
20672                     pkg = ps.pkg;
20673                 }
20674             }
20675 
20676             if (pkg == null) {
20677                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20678                 return false;
20679             }
20680 
20681             PackageSetting ps = (PackageSetting) pkg.mExtras;
20682             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20683         }
20684 
20685         clearAppDataLIF(pkg, userId,
20686                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20687 
20688         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20689         removeKeystoreDataIfNeeded(userId, appId);
20690 
20691         UserManagerInternal umInternal = getUserManagerInternal();
20692         final int flags;
20693         if (umInternal.isUserUnlockingOrUnlocked(userId)) {
20694             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20695         } else if (umInternal.isUserRunning(userId)) {
20696             flags = StorageManager.FLAG_STORAGE_DE;
20697         } else {
20698             flags = 0;
20699         }
20700         prepareAppDataContentsLIF(pkg, userId, flags);
20701 
20702         return true;
20703     }
20704 
20705     /**
20706      * Reverts user permission state changes (permissions and flags) in
20707      * all packages for a given user.
20708      *
20709      * @param userId The device user for which to do a reset.
20710      */
resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId)20711     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
20712         final int packageCount = mPackages.size();
20713         for (int i = 0; i < packageCount; i++) {
20714             PackageParser.Package pkg = mPackages.valueAt(i);
20715             PackageSetting ps = (PackageSetting) pkg.mExtras;
20716             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20717         }
20718     }
20719 
resetNetworkPolicies(int userId)20720     private void resetNetworkPolicies(int userId) {
20721         LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
20722     }
20723 
20724     /**
20725      * Reverts user permission state changes (permissions and flags).
20726      *
20727      * @param ps The package for which to reset.
20728      * @param userId The device user for which to do a reset.
20729      */
resetUserChangesToRuntimePermissionsAndFlagsLPw( final PackageSetting ps, final int userId)20730     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
20731             final PackageSetting ps, final int userId) {
20732         if (ps.pkg == null) {
20733             return;
20734         }
20735 
20736         // These are flags that can change base on user actions.
20737         final int userSettableMask = FLAG_PERMISSION_USER_SET
20738                 | FLAG_PERMISSION_USER_FIXED
20739                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
20740                 | FLAG_PERMISSION_REVIEW_REQUIRED;
20741 
20742         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
20743                 | FLAG_PERMISSION_POLICY_FIXED;
20744 
20745         boolean writeInstallPermissions = false;
20746         boolean writeRuntimePermissions = false;
20747 
20748         final int permissionCount = ps.pkg.requestedPermissions.size();
20749         for (int i = 0; i < permissionCount; i++) {
20750             String permission = ps.pkg.requestedPermissions.get(i);
20751 
20752             BasePermission bp = mSettings.mPermissions.get(permission);
20753             if (bp == null) {
20754                 continue;
20755             }
20756 
20757             // If shared user we just reset the state to which only this app contributed.
20758             if (ps.sharedUser != null) {
20759                 boolean used = false;
20760                 final int packageCount = ps.sharedUser.packages.size();
20761                 for (int j = 0; j < packageCount; j++) {
20762                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
20763                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
20764                             && pkg.pkg.requestedPermissions.contains(permission)) {
20765                         used = true;
20766                         break;
20767                     }
20768                 }
20769                 if (used) {
20770                     continue;
20771                 }
20772             }
20773 
20774             PermissionsState permissionsState = ps.getPermissionsState();
20775 
20776             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
20777 
20778             // Always clear the user settable flags.
20779             final boolean hasInstallState = permissionsState.getInstallPermissionState(
20780                     bp.name) != null;
20781             // If permission review is enabled and this is a legacy app, mark the
20782             // permission as requiring a review as this is the initial state.
20783             int flags = 0;
20784             if (mPermissionReviewRequired
20785                     && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
20786                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
20787             }
20788             if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
20789                 if (hasInstallState) {
20790                     writeInstallPermissions = true;
20791                 } else {
20792                     writeRuntimePermissions = true;
20793                 }
20794             }
20795 
20796             // Below is only runtime permission handling.
20797             if (!bp.isRuntime()) {
20798                 continue;
20799             }
20800 
20801             // Never clobber system or policy.
20802             if ((oldFlags & policyOrSystemFlags) != 0) {
20803                 continue;
20804             }
20805 
20806             // If this permission was granted by default, make sure it is.
20807             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
20808                 if (permissionsState.grantRuntimePermission(bp, userId)
20809                         != PERMISSION_OPERATION_FAILURE) {
20810                     writeRuntimePermissions = true;
20811                 }
20812             // If permission review is enabled the permissions for a legacy apps
20813             // are represented as constantly granted runtime ones, so don't revoke.
20814             } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
20815                 // Otherwise, reset the permission.
20816                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
20817                 switch (revokeResult) {
20818                     case PERMISSION_OPERATION_SUCCESS:
20819                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
20820                         writeRuntimePermissions = true;
20821                         final int appId = ps.appId;
20822                         mHandler.post(new Runnable() {
20823                             @Override
20824                             public void run() {
20825                                 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
20826                             }
20827                         });
20828                     } break;
20829                 }
20830             }
20831         }
20832 
20833         // Synchronously write as we are taking permissions away.
20834         if (writeRuntimePermissions) {
20835             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
20836         }
20837 
20838         // Synchronously write as we are taking permissions away.
20839         if (writeInstallPermissions) {
20840             mSettings.writeLPr();
20841         }
20842     }
20843 
20844     /**
20845      * Remove entries from the keystore daemon. Will only remove it if the
20846      * {@code appId} is valid.
20847      */
removeKeystoreDataIfNeeded(int userId, int appId)20848     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
20849         if (appId < 0) {
20850             return;
20851         }
20852 
20853         final KeyStore keyStore = KeyStore.getInstance();
20854         if (keyStore != null) {
20855             if (userId == UserHandle.USER_ALL) {
20856                 for (final int individual : sUserManager.getUserIds()) {
20857                     keyStore.clearUid(UserHandle.getUid(individual, appId));
20858                 }
20859             } else {
20860                 keyStore.clearUid(UserHandle.getUid(userId, appId));
20861             }
20862         } else {
20863             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20864         }
20865     }
20866 
20867     @Override
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)20868     public void deleteApplicationCacheFiles(final String packageName,
20869             final IPackageDataObserver observer) {
20870         final int userId = UserHandle.getCallingUserId();
20871         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20872     }
20873 
20874     @Override
deleteApplicationCacheFilesAsUser(final String packageName, final int userId, final IPackageDataObserver observer)20875     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20876             final IPackageDataObserver observer) {
20877         final int callingUid = Binder.getCallingUid();
20878         mContext.enforceCallingOrSelfPermission(
20879                 android.Manifest.permission.DELETE_CACHE_FILES, null);
20880         enforceCrossUserPermission(callingUid, userId,
20881                 /* requireFullPermission= */ true, /* checkShell= */ false,
20882                 "delete application cache files");
20883         final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20884                 android.Manifest.permission.ACCESS_INSTANT_APPS);
20885 
20886         final PackageParser.Package pkg;
20887         synchronized (mPackages) {
20888             pkg = mPackages.get(packageName);
20889         }
20890 
20891         // Queue up an async operation since the package deletion may take a little while.
20892         mHandler.post(new Runnable() {
20893             public void run() {
20894                 final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20895                 boolean doClearData = true;
20896                 if (ps != null) {
20897                     final boolean targetIsInstantApp =
20898                             ps.getInstantApp(UserHandle.getUserId(callingUid));
20899                     doClearData = !targetIsInstantApp
20900                             || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20901                 }
20902                 if (doClearData) {
20903                     synchronized (mInstallLock) {
20904                         final int flags = StorageManager.FLAG_STORAGE_DE
20905                                 | StorageManager.FLAG_STORAGE_CE;
20906                         // We're only clearing cache files, so we don't care if the
20907                         // app is unfrozen and still able to run
20908                         clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20909                         clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20910                     }
20911                     clearExternalStorageDataSync(packageName, userId, false);
20912                 }
20913                 if (observer != null) {
20914                     try {
20915                         observer.onRemoveCompleted(packageName, true);
20916                     } catch (RemoteException e) {
20917                         Log.i(TAG, "Observer no longer exists.");
20918                     }
20919                 }
20920             }
20921         });
20922     }
20923 
20924     @Override
getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)20925     public void getPackageSizeInfo(final String packageName, int userHandle,
20926             final IPackageStatsObserver observer) {
20927         throw new UnsupportedOperationException(
20928                 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20929     }
20930 
getPackageSizeInfoLI(String packageName, int userId, PackageStats stats)20931     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20932         final PackageSetting ps;
20933         synchronized (mPackages) {
20934             ps = mSettings.mPackages.get(packageName);
20935             if (ps == null) {
20936                 Slog.w(TAG, "Failed to find settings for " + packageName);
20937                 return false;
20938             }
20939         }
20940 
20941         final String[] packageNames = { packageName };
20942         final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20943         final String[] codePaths = { ps.codePathString };
20944 
20945         try {
20946             mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20947                     ps.appId, ceDataInodes, codePaths, stats);
20948 
20949             // For now, ignore code size of packages on system partition
20950             if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20951                 stats.codeSize = 0;
20952             }
20953 
20954             // External clients expect these to be tracked separately
20955             stats.dataSize -= stats.cacheSize;
20956 
20957         } catch (InstallerException e) {
20958             Slog.w(TAG, String.valueOf(e));
20959             return false;
20960         }
20961 
20962         return true;
20963     }
20964 
getUidTargetSdkVersionLockedLPr(int uid)20965     private int getUidTargetSdkVersionLockedLPr(int uid) {
20966         Object obj = mSettings.getUserIdLPr(uid);
20967         if (obj instanceof SharedUserSetting) {
20968             final SharedUserSetting sus = (SharedUserSetting) obj;
20969             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20970             final Iterator<PackageSetting> it = sus.packages.iterator();
20971             while (it.hasNext()) {
20972                 final PackageSetting ps = it.next();
20973                 if (ps.pkg != null) {
20974                     int v = ps.pkg.applicationInfo.targetSdkVersion;
20975                     if (v < vers) vers = v;
20976                 }
20977             }
20978             return vers;
20979         } else if (obj instanceof PackageSetting) {
20980             final PackageSetting ps = (PackageSetting) obj;
20981             if (ps.pkg != null) {
20982                 return ps.pkg.applicationInfo.targetSdkVersion;
20983             }
20984         }
20985         return Build.VERSION_CODES.CUR_DEVELOPMENT;
20986     }
20987 
20988     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)20989     public void addPreferredActivity(IntentFilter filter, int match,
20990             ComponentName[] set, ComponentName activity, int userId) {
20991         addPreferredActivityInternal(filter, match, set, activity, true, userId,
20992                 "Adding preferred");
20993     }
20994 
addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname)20995     private void addPreferredActivityInternal(IntentFilter filter, int match,
20996             ComponentName[] set, ComponentName activity, boolean always, int userId,
20997             String opname) {
20998         // writer
20999         int callingUid = Binder.getCallingUid();
21000         enforceCrossUserPermission(callingUid, userId,
21001                 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
21002         if (filter.countActions() == 0) {
21003             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
21004             return;
21005         }
21006         synchronized (mPackages) {
21007             if (mContext.checkCallingOrSelfPermission(
21008                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
21009                     != PackageManager.PERMISSION_GRANTED) {
21010                 if (getUidTargetSdkVersionLockedLPr(callingUid)
21011                         < Build.VERSION_CODES.FROYO) {
21012                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
21013                             + callingUid);
21014                     return;
21015                 }
21016                 mContext.enforceCallingOrSelfPermission(
21017                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21018             }
21019 
21020             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
21021             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
21022                     + userId + ":");
21023             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21024             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
21025             scheduleWritePackageRestrictionsLocked(userId);
21026             postPreferredActivityChangedBroadcast(userId);
21027         }
21028     }
21029 
postPreferredActivityChangedBroadcast(int userId)21030     private void postPreferredActivityChangedBroadcast(int userId) {
21031         mHandler.post(() -> {
21032             final IActivityManager am = ActivityManager.getService();
21033             if (am == null) {
21034                 return;
21035             }
21036 
21037             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
21038             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
21039             try {
21040                 am.broadcastIntent(null, intent, null, null,
21041                         0, null, null, null, android.app.AppOpsManager.OP_NONE,
21042                         null, false, false, userId);
21043             } catch (RemoteException e) {
21044             }
21045         });
21046     }
21047 
21048     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)21049     public void replacePreferredActivity(IntentFilter filter, int match,
21050             ComponentName[] set, ComponentName activity, int userId) {
21051         if (filter.countActions() != 1) {
21052             throw new IllegalArgumentException(
21053                     "replacePreferredActivity expects filter to have only 1 action.");
21054         }
21055         if (filter.countDataAuthorities() != 0
21056                 || filter.countDataPaths() != 0
21057                 || filter.countDataSchemes() > 1
21058                 || filter.countDataTypes() != 0) {
21059             throw new IllegalArgumentException(
21060                     "replacePreferredActivity expects filter to have no data authorities, " +
21061                     "paths, or types; and at most one scheme.");
21062         }
21063 
21064         final int callingUid = Binder.getCallingUid();
21065         enforceCrossUserPermission(callingUid, userId,
21066                 true /* requireFullPermission */, false /* checkShell */,
21067                 "replace preferred activity");
21068         synchronized (mPackages) {
21069             if (mContext.checkCallingOrSelfPermission(
21070                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
21071                     != PackageManager.PERMISSION_GRANTED) {
21072                 if (getUidTargetSdkVersionLockedLPr(callingUid)
21073                         < Build.VERSION_CODES.FROYO) {
21074                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
21075                             + Binder.getCallingUid());
21076                     return;
21077                 }
21078                 mContext.enforceCallingOrSelfPermission(
21079                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21080             }
21081 
21082             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
21083             if (pir != null) {
21084                 // Get all of the existing entries that exactly match this filter.
21085                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
21086                 if (existing != null && existing.size() == 1) {
21087                     PreferredActivity cur = existing.get(0);
21088                     if (DEBUG_PREFERRED) {
21089                         Slog.i(TAG, "Checking replace of preferred:");
21090                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21091                         if (!cur.mPref.mAlways) {
21092                             Slog.i(TAG, "  -- CUR; not mAlways!");
21093                         } else {
21094                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
21095                             Slog.i(TAG, "  -- CUR: mSet="
21096                                     + Arrays.toString(cur.mPref.mSetComponents));
21097                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
21098                             Slog.i(TAG, "  -- NEW: mMatch="
21099                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
21100                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
21101                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
21102                         }
21103                     }
21104                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
21105                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
21106                             && cur.mPref.sameSet(set)) {
21107                         // Setting the preferred activity to what it happens to be already
21108                         if (DEBUG_PREFERRED) {
21109                             Slog.i(TAG, "Replacing with same preferred activity "
21110                                     + cur.mPref.mShortComponent + " for user "
21111                                     + userId + ":");
21112                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21113                         }
21114                         return;
21115                     }
21116                 }
21117 
21118                 if (existing != null) {
21119                     if (DEBUG_PREFERRED) {
21120                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
21121                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21122                     }
21123                     for (int i = 0; i < existing.size(); i++) {
21124                         PreferredActivity pa = existing.get(i);
21125                         if (DEBUG_PREFERRED) {
21126                             Slog.i(TAG, "Removing existing preferred activity "
21127                                     + pa.mPref.mComponent + ":");
21128                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
21129                         }
21130                         pir.removeFilter(pa);
21131                     }
21132                 }
21133             }
21134             addPreferredActivityInternal(filter, match, set, activity, true, userId,
21135                     "Replacing preferred");
21136         }
21137     }
21138 
21139     @Override
clearPackagePreferredActivities(String packageName)21140     public void clearPackagePreferredActivities(String packageName) {
21141         final int callingUid = Binder.getCallingUid();
21142         if (getInstantAppPackageName(callingUid) != null) {
21143             return;
21144         }
21145         // writer
21146         synchronized (mPackages) {
21147             PackageParser.Package pkg = mPackages.get(packageName);
21148             if (pkg == null || pkg.applicationInfo.uid != callingUid) {
21149                 if (mContext.checkCallingOrSelfPermission(
21150                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
21151                         != PackageManager.PERMISSION_GRANTED) {
21152                     if (getUidTargetSdkVersionLockedLPr(callingUid)
21153                             < Build.VERSION_CODES.FROYO) {
21154                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
21155                                 + callingUid);
21156                         return;
21157                     }
21158                     mContext.enforceCallingOrSelfPermission(
21159                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21160                 }
21161             }
21162             final PackageSetting ps = mSettings.getPackageLPr(packageName);
21163             if (ps != null
21164                     && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21165                 return;
21166             }
21167             int user = UserHandle.getCallingUserId();
21168             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
21169                 scheduleWritePackageRestrictionsLocked(user);
21170             }
21171         }
21172     }
21173 
21174     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearPackagePreferredActivitiesLPw(String packageName, int userId)21175     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
21176         ArrayList<PreferredActivity> removed = null;
21177         boolean changed = false;
21178         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21179             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
21180             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21181             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
21182                 continue;
21183             }
21184             Iterator<PreferredActivity> it = pir.filterIterator();
21185             while (it.hasNext()) {
21186                 PreferredActivity pa = it.next();
21187                 // Mark entry for removal only if it matches the package name
21188                 // and the entry is of type "always".
21189                 if (packageName == null ||
21190                         (pa.mPref.mComponent.getPackageName().equals(packageName)
21191                                 && pa.mPref.mAlways)) {
21192                     if (removed == null) {
21193                         removed = new ArrayList<PreferredActivity>();
21194                     }
21195                     removed.add(pa);
21196                 }
21197             }
21198             if (removed != null) {
21199                 for (int j=0; j<removed.size(); j++) {
21200                     PreferredActivity pa = removed.get(j);
21201                     pir.removeFilter(pa);
21202                 }
21203                 changed = true;
21204             }
21205         }
21206         if (changed) {
21207             postPreferredActivityChangedBroadcast(userId);
21208         }
21209         return changed;
21210     }
21211 
21212     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearIntentFilterVerificationsLPw(int userId)21213     private void clearIntentFilterVerificationsLPw(int userId) {
21214         final int packageCount = mPackages.size();
21215         for (int i = 0; i < packageCount; i++) {
21216             PackageParser.Package pkg = mPackages.valueAt(i);
21217             clearIntentFilterVerificationsLPw(pkg.packageName, userId, true);
21218         }
21219     }
21220 
21221     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearIntentFilterVerificationsLPw(String packageName, int userId, boolean alsoResetStatus)21222     void clearIntentFilterVerificationsLPw(String packageName, int userId,
21223             boolean alsoResetStatus) {
21224         if (userId == UserHandle.USER_ALL) {
21225             if (mSettings.removeIntentFilterVerificationLPw(packageName,
21226                     sUserManager.getUserIds())) {
21227                 for (int oneUserId : sUserManager.getUserIds()) {
21228                     scheduleWritePackageRestrictionsLocked(oneUserId);
21229                 }
21230             }
21231         } else {
21232             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId,
21233                     alsoResetStatus)) {
21234                 scheduleWritePackageRestrictionsLocked(userId);
21235             }
21236         }
21237     }
21238 
21239     /** Clears state for all users, and touches intent filter verification policy */
clearDefaultBrowserIfNeeded(String packageName)21240     void clearDefaultBrowserIfNeeded(String packageName) {
21241         for (int oneUserId : sUserManager.getUserIds()) {
21242             clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
21243         }
21244     }
21245 
clearDefaultBrowserIfNeededForUser(String packageName, int userId)21246     private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
21247         final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
21248         if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
21249             if (packageName.equals(defaultBrowserPackageName)) {
21250                 setDefaultBrowserPackageName(null, userId);
21251             }
21252         }
21253     }
21254 
21255     @Override
resetApplicationPreferences(int userId)21256     public void resetApplicationPreferences(int userId) {
21257         mContext.enforceCallingOrSelfPermission(
21258                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21259         final long identity = Binder.clearCallingIdentity();
21260         // writer
21261         try {
21262             synchronized (mPackages) {
21263                 clearPackagePreferredActivitiesLPw(null, userId);
21264                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
21265                 // TODO: We have to reset the default SMS and Phone. This requires
21266                 // significant refactoring to keep all default apps in the package
21267                 // manager (cleaner but more work) or have the services provide
21268                 // callbacks to the package manager to request a default app reset.
21269                 applyFactoryDefaultBrowserLPw(userId);
21270                 clearIntentFilterVerificationsLPw(userId);
21271                 primeDomainVerificationsLPw(userId);
21272                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
21273                 scheduleWritePackageRestrictionsLocked(userId);
21274             }
21275             resetNetworkPolicies(userId);
21276         } finally {
21277             Binder.restoreCallingIdentity(identity);
21278         }
21279     }
21280 
21281     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)21282     public int getPreferredActivities(List<IntentFilter> outFilters,
21283             List<ComponentName> outActivities, String packageName) {
21284         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21285             return 0;
21286         }
21287         int num = 0;
21288         final int userId = UserHandle.getCallingUserId();
21289         // reader
21290         synchronized (mPackages) {
21291             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
21292             if (pir != null) {
21293                 final Iterator<PreferredActivity> it = pir.filterIterator();
21294                 while (it.hasNext()) {
21295                     final PreferredActivity pa = it.next();
21296                     if (packageName == null
21297                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
21298                                     && pa.mPref.mAlways)) {
21299                         if (outFilters != null) {
21300                             outFilters.add(new IntentFilter(pa));
21301                         }
21302                         if (outActivities != null) {
21303                             outActivities.add(pa.mPref.mComponent);
21304                         }
21305                     }
21306                 }
21307             }
21308         }
21309 
21310         return num;
21311     }
21312 
21313     @Override
addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)21314     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
21315             int userId) {
21316         int callingUid = Binder.getCallingUid();
21317         if (callingUid != Process.SYSTEM_UID) {
21318             throw new SecurityException(
21319                     "addPersistentPreferredActivity can only be run by the system");
21320         }
21321         if (filter.countActions() == 0) {
21322             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
21323             return;
21324         }
21325         synchronized (mPackages) {
21326             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
21327                     ":");
21328             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21329             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
21330                     new PersistentPreferredActivity(filter, activity));
21331             scheduleWritePackageRestrictionsLocked(userId);
21332             postPreferredActivityChangedBroadcast(userId);
21333         }
21334     }
21335 
21336     @Override
clearPackagePersistentPreferredActivities(String packageName, int userId)21337     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
21338         int callingUid = Binder.getCallingUid();
21339         if (callingUid != Process.SYSTEM_UID) {
21340             throw new SecurityException(
21341                     "clearPackagePersistentPreferredActivities can only be run by the system");
21342         }
21343         ArrayList<PersistentPreferredActivity> removed = null;
21344         boolean changed = false;
21345         synchronized (mPackages) {
21346             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
21347                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
21348                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
21349                         .valueAt(i);
21350                 if (userId != thisUserId) {
21351                     continue;
21352                 }
21353                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
21354                 while (it.hasNext()) {
21355                     PersistentPreferredActivity ppa = it.next();
21356                     // Mark entry for removal only if it matches the package name.
21357                     if (ppa.mComponent.getPackageName().equals(packageName)) {
21358                         if (removed == null) {
21359                             removed = new ArrayList<PersistentPreferredActivity>();
21360                         }
21361                         removed.add(ppa);
21362                     }
21363                 }
21364                 if (removed != null) {
21365                     for (int j=0; j<removed.size(); j++) {
21366                         PersistentPreferredActivity ppa = removed.get(j);
21367                         ppir.removeFilter(ppa);
21368                     }
21369                     changed = true;
21370                 }
21371             }
21372 
21373             if (changed) {
21374                 scheduleWritePackageRestrictionsLocked(userId);
21375                 postPreferredActivityChangedBroadcast(userId);
21376             }
21377         }
21378     }
21379 
21380     /**
21381      * Common machinery for picking apart a restored XML blob and passing
21382      * it to a caller-supplied functor to be applied to the running system.
21383      */
restoreFromXml(XmlPullParser parser, int userId, String expectedStartTag, BlobXmlRestorer functor)21384     private void restoreFromXml(XmlPullParser parser, int userId,
21385             String expectedStartTag, BlobXmlRestorer functor)
21386             throws IOException, XmlPullParserException {
21387         int type;
21388         while ((type = parser.next()) != XmlPullParser.START_TAG
21389                 && type != XmlPullParser.END_DOCUMENT) {
21390         }
21391         if (type != XmlPullParser.START_TAG) {
21392             // oops didn't find a start tag?!
21393             if (DEBUG_BACKUP) {
21394                 Slog.e(TAG, "Didn't find start tag during restore");
21395             }
21396             return;
21397         }
21398 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
21399         // this is supposed to be TAG_PREFERRED_BACKUP
21400         if (!expectedStartTag.equals(parser.getName())) {
21401             if (DEBUG_BACKUP) {
21402                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
21403             }
21404             return;
21405         }
21406 
21407         // skip interfering stuff, then we're aligned with the backing implementation
21408         while ((type = parser.next()) == XmlPullParser.TEXT) { }
21409 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
21410         functor.apply(parser, userId);
21411     }
21412 
21413     private interface BlobXmlRestorer {
apply(XmlPullParser parser, int userId)21414         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
21415     }
21416 
21417     /**
21418      * Non-Binder method, support for the backup/restore mechanism: write the
21419      * full set of preferred activities in its canonical XML format.  Returns the
21420      * XML output as a byte array, or null if there is none.
21421      */
21422     @Override
getPreferredActivityBackup(int userId)21423     public byte[] getPreferredActivityBackup(int userId) {
21424         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21425             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
21426         }
21427 
21428         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21429         try {
21430             final XmlSerializer serializer = new FastXmlSerializer();
21431             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21432             serializer.startDocument(null, true);
21433             serializer.startTag(null, TAG_PREFERRED_BACKUP);
21434 
21435             synchronized (mPackages) {
21436                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
21437             }
21438 
21439             serializer.endTag(null, TAG_PREFERRED_BACKUP);
21440             serializer.endDocument();
21441             serializer.flush();
21442         } catch (Exception e) {
21443             if (DEBUG_BACKUP) {
21444                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
21445             }
21446             return null;
21447         }
21448 
21449         return dataStream.toByteArray();
21450     }
21451 
21452     @Override
restorePreferredActivities(byte[] backup, int userId)21453     public void restorePreferredActivities(byte[] backup, int userId) {
21454         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21455             throw new SecurityException("Only the system may call restorePreferredActivities()");
21456         }
21457 
21458         try {
21459             final XmlPullParser parser = Xml.newPullParser();
21460             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21461             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
21462                     new BlobXmlRestorer() {
21463                         @Override
21464                         public void apply(XmlPullParser parser, int userId)
21465                                 throws XmlPullParserException, IOException {
21466                             synchronized (mPackages) {
21467                                 mSettings.readPreferredActivitiesLPw(parser, userId);
21468                             }
21469                         }
21470                     } );
21471         } catch (Exception e) {
21472             if (DEBUG_BACKUP) {
21473                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21474             }
21475         }
21476     }
21477 
21478     /**
21479      * Non-Binder method, support for the backup/restore mechanism: write the
21480      * default browser (etc) settings in its canonical XML format.  Returns the default
21481      * browser XML representation as a byte array, or null if there is none.
21482      */
21483     @Override
getDefaultAppsBackup(int userId)21484     public byte[] getDefaultAppsBackup(int userId) {
21485         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21486             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
21487         }
21488 
21489         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21490         try {
21491             final XmlSerializer serializer = new FastXmlSerializer();
21492             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21493             serializer.startDocument(null, true);
21494             serializer.startTag(null, TAG_DEFAULT_APPS);
21495 
21496             synchronized (mPackages) {
21497                 mSettings.writeDefaultAppsLPr(serializer, userId);
21498             }
21499 
21500             serializer.endTag(null, TAG_DEFAULT_APPS);
21501             serializer.endDocument();
21502             serializer.flush();
21503         } catch (Exception e) {
21504             if (DEBUG_BACKUP) {
21505                 Slog.e(TAG, "Unable to write default apps for backup", e);
21506             }
21507             return null;
21508         }
21509 
21510         return dataStream.toByteArray();
21511     }
21512 
21513     @Override
restoreDefaultApps(byte[] backup, int userId)21514     public void restoreDefaultApps(byte[] backup, int userId) {
21515         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21516             throw new SecurityException("Only the system may call restoreDefaultApps()");
21517         }
21518 
21519         try {
21520             final XmlPullParser parser = Xml.newPullParser();
21521             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21522             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
21523                     new BlobXmlRestorer() {
21524                         @Override
21525                         public void apply(XmlPullParser parser, int userId)
21526                                 throws XmlPullParserException, IOException {
21527                             synchronized (mPackages) {
21528                                 mSettings.readDefaultAppsLPw(parser, userId);
21529                             }
21530                         }
21531                     } );
21532         } catch (Exception e) {
21533             if (DEBUG_BACKUP) {
21534                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
21535             }
21536         }
21537     }
21538 
21539     @Override
getIntentFilterVerificationBackup(int userId)21540     public byte[] getIntentFilterVerificationBackup(int userId) {
21541         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21542             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
21543         }
21544 
21545         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21546         try {
21547             final XmlSerializer serializer = new FastXmlSerializer();
21548             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21549             serializer.startDocument(null, true);
21550             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
21551 
21552             synchronized (mPackages) {
21553                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
21554             }
21555 
21556             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
21557             serializer.endDocument();
21558             serializer.flush();
21559         } catch (Exception e) {
21560             if (DEBUG_BACKUP) {
21561                 Slog.e(TAG, "Unable to write default apps for backup", e);
21562             }
21563             return null;
21564         }
21565 
21566         return dataStream.toByteArray();
21567     }
21568 
21569     @Override
restoreIntentFilterVerification(byte[] backup, int userId)21570     public void restoreIntentFilterVerification(byte[] backup, int userId) {
21571         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21572             throw new SecurityException("Only the system may call restorePreferredActivities()");
21573         }
21574 
21575         try {
21576             final XmlPullParser parser = Xml.newPullParser();
21577             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21578             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
21579                     new BlobXmlRestorer() {
21580                         @Override
21581                         public void apply(XmlPullParser parser, int userId)
21582                                 throws XmlPullParserException, IOException {
21583                             synchronized (mPackages) {
21584                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
21585                                 mSettings.writeLPr();
21586                             }
21587                         }
21588                     } );
21589         } catch (Exception e) {
21590             if (DEBUG_BACKUP) {
21591                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21592             }
21593         }
21594     }
21595 
21596     @Override
getPermissionGrantBackup(int userId)21597     public byte[] getPermissionGrantBackup(int userId) {
21598         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21599             throw new SecurityException("Only the system may call getPermissionGrantBackup()");
21600         }
21601 
21602         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21603         try {
21604             final XmlSerializer serializer = new FastXmlSerializer();
21605             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21606             serializer.startDocument(null, true);
21607             serializer.startTag(null, TAG_PERMISSION_BACKUP);
21608 
21609             synchronized (mPackages) {
21610                 serializeRuntimePermissionGrantsLPr(serializer, userId);
21611             }
21612 
21613             serializer.endTag(null, TAG_PERMISSION_BACKUP);
21614             serializer.endDocument();
21615             serializer.flush();
21616         } catch (Exception e) {
21617             if (DEBUG_BACKUP) {
21618                 Slog.e(TAG, "Unable to write default apps for backup", e);
21619             }
21620             return null;
21621         }
21622 
21623         return dataStream.toByteArray();
21624     }
21625 
21626     @Override
restorePermissionGrants(byte[] backup, int userId)21627     public void restorePermissionGrants(byte[] backup, int userId) {
21628         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21629             throw new SecurityException("Only the system may call restorePermissionGrants()");
21630         }
21631 
21632         try {
21633             final XmlPullParser parser = Xml.newPullParser();
21634             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21635             restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
21636                     new BlobXmlRestorer() {
21637                         @Override
21638                         public void apply(XmlPullParser parser, int userId)
21639                                 throws XmlPullParserException, IOException {
21640                             synchronized (mPackages) {
21641                                 processRestoredPermissionGrantsLPr(parser, userId);
21642                             }
21643                         }
21644                     } );
21645         } catch (Exception e) {
21646             if (DEBUG_BACKUP) {
21647                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21648             }
21649         }
21650     }
21651 
serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)21652     private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
21653             throws IOException {
21654         serializer.startTag(null, TAG_ALL_GRANTS);
21655 
21656         final int N = mSettings.mPackages.size();
21657         for (int i = 0; i < N; i++) {
21658             final PackageSetting ps = mSettings.mPackages.valueAt(i);
21659             boolean pkgGrantsKnown = false;
21660 
21661             PermissionsState packagePerms = ps.getPermissionsState();
21662 
21663             for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
21664                 final int grantFlags = state.getFlags();
21665                 // only look at grants that are not system/policy fixed
21666                 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
21667                     final boolean isGranted = state.isGranted();
21668                     // And only back up the user-twiddled state bits
21669                     if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
21670                         final String packageName = mSettings.mPackages.keyAt(i);
21671                         if (!pkgGrantsKnown) {
21672                             serializer.startTag(null, TAG_GRANT);
21673                             serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
21674                             pkgGrantsKnown = true;
21675                         }
21676 
21677                         final boolean userSet =
21678                                 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
21679                         final boolean userFixed =
21680                                 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
21681                         final boolean revoke =
21682                                 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
21683 
21684                         serializer.startTag(null, TAG_PERMISSION);
21685                         serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
21686                         if (isGranted) {
21687                             serializer.attribute(null, ATTR_IS_GRANTED, "true");
21688                         }
21689                         if (userSet) {
21690                             serializer.attribute(null, ATTR_USER_SET, "true");
21691                         }
21692                         if (userFixed) {
21693                             serializer.attribute(null, ATTR_USER_FIXED, "true");
21694                         }
21695                         if (revoke) {
21696                             serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
21697                         }
21698                         serializer.endTag(null, TAG_PERMISSION);
21699                     }
21700                 }
21701             }
21702 
21703             if (pkgGrantsKnown) {
21704                 serializer.endTag(null, TAG_GRANT);
21705             }
21706         }
21707 
21708         serializer.endTag(null, TAG_ALL_GRANTS);
21709     }
21710 
processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)21711     private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
21712             throws XmlPullParserException, IOException {
21713         String pkgName = null;
21714         int outerDepth = parser.getDepth();
21715         int type;
21716         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
21717                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
21718             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
21719                 continue;
21720             }
21721 
21722             final String tagName = parser.getName();
21723             if (tagName.equals(TAG_GRANT)) {
21724                 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
21725                 if (DEBUG_BACKUP) {
21726                     Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
21727                 }
21728             } else if (tagName.equals(TAG_PERMISSION)) {
21729 
21730                 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
21731                 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
21732 
21733                 int newFlagSet = 0;
21734                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
21735                     newFlagSet |= FLAG_PERMISSION_USER_SET;
21736                 }
21737                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
21738                     newFlagSet |= FLAG_PERMISSION_USER_FIXED;
21739                 }
21740                 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
21741                     newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
21742                 }
21743                 if (DEBUG_BACKUP) {
21744                     Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
21745                             + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
21746                 }
21747                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
21748                 if (ps != null) {
21749                     // Already installed so we apply the grant immediately
21750                     if (DEBUG_BACKUP) {
21751                         Slog.v(TAG, "        + already installed; applying");
21752                     }
21753                     PermissionsState perms = ps.getPermissionsState();
21754                     BasePermission bp = mSettings.mPermissions.get(permName);
21755                     if (bp != null) {
21756                         if (isGranted) {
21757                             perms.grantRuntimePermission(bp, userId);
21758                         }
21759                         if (newFlagSet != 0) {
21760                             perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
21761                         }
21762                     }
21763                 } else {
21764                     // Need to wait for post-restore install to apply the grant
21765                     if (DEBUG_BACKUP) {
21766                         Slog.v(TAG, "        - not yet installed; saving for later");
21767                     }
21768                     mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
21769                             isGranted, newFlagSet, userId);
21770                 }
21771             } else {
21772                 PackageManagerService.reportSettingsProblem(Log.WARN,
21773                         "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
21774                 XmlUtils.skipCurrentTag(parser);
21775             }
21776         }
21777 
21778         scheduleWriteSettingsLocked();
21779         mSettings.writeRuntimePermissionsForUserLPr(userId, false);
21780     }
21781 
21782     @Override
addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)21783     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
21784             int sourceUserId, int targetUserId, int flags) {
21785         mContext.enforceCallingOrSelfPermission(
21786                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21787         int callingUid = Binder.getCallingUid();
21788         enforceOwnerRights(ownerPackage, callingUid);
21789         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21790         if (intentFilter.countActions() == 0) {
21791             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
21792             return;
21793         }
21794         synchronized (mPackages) {
21795             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
21796                     ownerPackage, targetUserId, flags);
21797             CrossProfileIntentResolver resolver =
21798                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21799             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
21800             // We have all those whose filter is equal. Now checking if the rest is equal as well.
21801             if (existing != null) {
21802                 int size = existing.size();
21803                 for (int i = 0; i < size; i++) {
21804                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
21805                         return;
21806                     }
21807                 }
21808             }
21809             resolver.addFilter(newFilter);
21810             scheduleWritePackageRestrictionsLocked(sourceUserId);
21811         }
21812     }
21813 
21814     @Override
clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage)21815     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
21816         mContext.enforceCallingOrSelfPermission(
21817                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21818         final int callingUid = Binder.getCallingUid();
21819         enforceOwnerRights(ownerPackage, callingUid);
21820         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21821         synchronized (mPackages) {
21822             CrossProfileIntentResolver resolver =
21823                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21824             ArraySet<CrossProfileIntentFilter> set =
21825                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
21826             for (CrossProfileIntentFilter filter : set) {
21827                 if (filter.getOwnerPackage().equals(ownerPackage)) {
21828                     resolver.removeFilter(filter);
21829                 }
21830             }
21831             scheduleWritePackageRestrictionsLocked(sourceUserId);
21832         }
21833     }
21834 
21835     // Enforcing that callingUid is owning pkg on userId
enforceOwnerRights(String pkg, int callingUid)21836     private void enforceOwnerRights(String pkg, int callingUid) {
21837         // The system owns everything.
21838         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21839             return;
21840         }
21841         final int callingUserId = UserHandle.getUserId(callingUid);
21842         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
21843         if (pi == null) {
21844             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
21845                     + callingUserId);
21846         }
21847         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
21848             throw new SecurityException("Calling uid " + callingUid
21849                     + " does not own package " + pkg);
21850         }
21851     }
21852 
21853     @Override
getHomeActivities(List<ResolveInfo> allHomeCandidates)21854     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
21855         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21856             return null;
21857         }
21858         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
21859     }
21860 
sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId)21861     public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
21862         UserManagerService ums = UserManagerService.getInstance();
21863         if (ums != null) {
21864             final UserInfo parent = ums.getProfileParent(userId);
21865             final int launcherUid = (parent != null) ? parent.id : userId;
21866             final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
21867             if (launcherComponent != null) {
21868                 Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
21869                         .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
21870                         .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
21871                         .setPackage(launcherComponent.getPackageName());
21872                 mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
21873             }
21874         }
21875     }
21876 
21877     /**
21878      * Report the 'Home' activity which is currently set as "always use this one". If non is set
21879      * then reports the most likely home activity or null if there are more than one.
21880      */
getDefaultHomeActivity(int userId)21881     private ComponentName getDefaultHomeActivity(int userId) {
21882         List<ResolveInfo> allHomeCandidates = new ArrayList<>();
21883         ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
21884         if (cn != null) {
21885             return cn;
21886         }
21887 
21888         // Find the launcher with the highest priority and return that component if there are no
21889         // other home activity with the same priority.
21890         int lastPriority = Integer.MIN_VALUE;
21891         ComponentName lastComponent = null;
21892         final int size = allHomeCandidates.size();
21893         for (int i = 0; i < size; i++) {
21894             final ResolveInfo ri = allHomeCandidates.get(i);
21895             if (ri.priority > lastPriority) {
21896                 lastComponent = ri.activityInfo.getComponentName();
21897                 lastPriority = ri.priority;
21898             } else if (ri.priority == lastPriority) {
21899                 // Two components found with same priority.
21900                 lastComponent = null;
21901             }
21902         }
21903         return lastComponent;
21904     }
21905 
getHomeIntent()21906     private Intent getHomeIntent() {
21907         Intent intent = new Intent(Intent.ACTION_MAIN);
21908         intent.addCategory(Intent.CATEGORY_HOME);
21909         intent.addCategory(Intent.CATEGORY_DEFAULT);
21910         return intent;
21911     }
21912 
getHomeFilter()21913     private IntentFilter getHomeFilter() {
21914         IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21915         filter.addCategory(Intent.CATEGORY_HOME);
21916         filter.addCategory(Intent.CATEGORY_DEFAULT);
21917         return filter;
21918     }
21919 
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)21920     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21921             int userId) {
21922         Intent intent  = getHomeIntent();
21923         List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21924                 PackageManager.GET_META_DATA, userId);
21925         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21926                 true, false, false, userId);
21927 
21928         allHomeCandidates.clear();
21929         if (list != null) {
21930             for (ResolveInfo ri : list) {
21931                 allHomeCandidates.add(ri);
21932             }
21933         }
21934         return (preferred == null || preferred.activityInfo == null)
21935                 ? null
21936                 : new ComponentName(preferred.activityInfo.packageName,
21937                         preferred.activityInfo.name);
21938     }
21939 
21940     @Override
setHomeActivity(ComponentName comp, int userId)21941     public void setHomeActivity(ComponentName comp, int userId) {
21942         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21943             return;
21944         }
21945         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21946         getHomeActivitiesAsUser(homeActivities, userId);
21947 
21948         boolean found = false;
21949 
21950         final int size = homeActivities.size();
21951         final ComponentName[] set = new ComponentName[size];
21952         for (int i = 0; i < size; i++) {
21953             final ResolveInfo candidate = homeActivities.get(i);
21954             final ActivityInfo info = candidate.activityInfo;
21955             final ComponentName activityName = new ComponentName(info.packageName, info.name);
21956             set[i] = activityName;
21957             if (!found && activityName.equals(comp)) {
21958                 found = true;
21959             }
21960         }
21961         if (!found) {
21962             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21963                     + userId);
21964         }
21965         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21966                 set, comp, userId);
21967     }
21968 
getSetupWizardPackageName()21969     private @Nullable String getSetupWizardPackageName() {
21970         final Intent intent = new Intent(Intent.ACTION_MAIN);
21971         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21972 
21973         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21974                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21975                         | MATCH_DISABLED_COMPONENTS,
21976                 UserHandle.myUserId());
21977         if (matches.size() == 1) {
21978             return matches.get(0).getComponentInfo().packageName;
21979         } else {
21980             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21981                     + ": matches=" + matches);
21982             return null;
21983         }
21984     }
21985 
getStorageManagerPackageName()21986     private @Nullable String getStorageManagerPackageName() {
21987         final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21988 
21989         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21990                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21991                         | MATCH_DISABLED_COMPONENTS,
21992                 UserHandle.myUserId());
21993         if (matches.size() == 1) {
21994             return matches.get(0).getComponentInfo().packageName;
21995         } else {
21996             Slog.e(TAG, "There should probably be exactly one storage manager; found "
21997                     + matches.size() + ": matches=" + matches);
21998             return null;
21999         }
22000     }
22001 
22002     @Override
setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)22003     public void setApplicationEnabledSetting(String appPackageName,
22004             int newState, int flags, int userId, String callingPackage) {
22005         if (!sUserManager.exists(userId)) return;
22006         if (callingPackage == null) {
22007             callingPackage = Integer.toString(Binder.getCallingUid());
22008         }
22009         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
22010     }
22011 
22012     @Override
setUpdateAvailable(String packageName, boolean updateAvailable)22013     public void setUpdateAvailable(String packageName, boolean updateAvailable) {
22014         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
22015         synchronized (mPackages) {
22016             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
22017             if (pkgSetting != null) {
22018                 pkgSetting.setUpdateAvailable(updateAvailable);
22019             }
22020         }
22021     }
22022 
22023     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)22024     public void setComponentEnabledSetting(ComponentName componentName,
22025             int newState, int flags, int userId) {
22026         if (!sUserManager.exists(userId)) return;
22027         setEnabledSetting(componentName.getPackageName(),
22028                 componentName.getClassName(), newState, flags, userId, null);
22029     }
22030 
setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)22031     private void setEnabledSetting(final String packageName, String className, int newState,
22032             final int flags, int userId, String callingPackage) {
22033         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
22034               || newState == COMPONENT_ENABLED_STATE_ENABLED
22035               || newState == COMPONENT_ENABLED_STATE_DISABLED
22036               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
22037               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
22038             throw new IllegalArgumentException("Invalid new component state: "
22039                     + newState);
22040         }
22041         PackageSetting pkgSetting;
22042         final int callingUid = Binder.getCallingUid();
22043         final int permission;
22044         if (callingUid == Process.SYSTEM_UID) {
22045             permission = PackageManager.PERMISSION_GRANTED;
22046         } else {
22047             permission = mContext.checkCallingOrSelfPermission(
22048                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
22049         }
22050         enforceCrossUserPermission(callingUid, userId,
22051                 false /* requireFullPermission */, true /* checkShell */, "set enabled");
22052         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
22053         boolean sendNow = false;
22054         boolean isApp = (className == null);
22055         final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
22056         String componentName = isApp ? packageName : className;
22057         int packageUid = -1;
22058         ArrayList<String> components;
22059 
22060         // reader
22061         synchronized (mPackages) {
22062             pkgSetting = mSettings.mPackages.get(packageName);
22063             if (pkgSetting == null) {
22064                 if (!isCallerInstantApp) {
22065                     if (className == null) {
22066                         throw new IllegalArgumentException("Unknown package: " + packageName);
22067                     }
22068                     throw new IllegalArgumentException(
22069                             "Unknown component: " + packageName + "/" + className);
22070                 } else {
22071                     // throw SecurityException to prevent leaking package information
22072                     throw new SecurityException(
22073                             "Attempt to change component state; "
22074                             + "pid=" + Binder.getCallingPid()
22075                             + ", uid=" + callingUid
22076                             + (className == null
22077                                     ? ", package=" + packageName
22078                                     : ", component=" + packageName + "/" + className));
22079                 }
22080             }
22081         }
22082 
22083         // Limit who can change which apps
22084         if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
22085             // Don't allow apps that don't have permission to modify other apps
22086             if (!allowedByPermission
22087                     || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
22088                 throw new SecurityException(
22089                         "Attempt to change component state; "
22090                         + "pid=" + Binder.getCallingPid()
22091                         + ", uid=" + callingUid
22092                         + (className == null
22093                                 ? ", package=" + packageName
22094                                 : ", component=" + packageName + "/" + className));
22095             }
22096             // Don't allow changing protected packages.
22097             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
22098                 throw new SecurityException("Cannot disable a protected package: " + packageName);
22099             }
22100         }
22101 
22102         synchronized (mPackages) {
22103             if (callingUid == Process.SHELL_UID
22104                     && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
22105                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
22106                 // unless it is a test package.
22107                 int oldState = pkgSetting.getEnabled(userId);
22108                 if (className == null
22109                         &&
22110                         (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
22111                                 || oldState == COMPONENT_ENABLED_STATE_DEFAULT
22112                                 || oldState == COMPONENT_ENABLED_STATE_ENABLED)
22113                         &&
22114                         (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
22115                                 || newState == COMPONENT_ENABLED_STATE_DEFAULT
22116                                 || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
22117                     // ok
22118                 } else {
22119                     throw new SecurityException(
22120                             "Shell cannot change component state for " + packageName + "/"
22121                                     + className + " to " + newState);
22122                 }
22123             }
22124         }
22125         if (className == null) {
22126             // We're dealing with an application/package level state change
22127             synchronized (mPackages) {
22128                 if (pkgSetting.getEnabled(userId) == newState) {
22129                     // Nothing to do
22130                     return;
22131                 }
22132             }
22133             // If we're enabling a system stub, there's a little more work to do.
22134             // Prior to enabling the package, we need to decompress the APK(s) to the
22135             // data partition and then replace the version on the system partition.
22136             final PackageParser.Package deletedPkg = pkgSetting.pkg;
22137             final boolean isSystemStub = deletedPkg.isStub
22138                     && deletedPkg.isSystemApp();
22139             if (isSystemStub
22140                     && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
22141                             || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
22142                 final File codePath = decompressPackage(deletedPkg);
22143                 if (codePath == null) {
22144                     Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
22145                     return;
22146                 }
22147                 // TODO remove direct parsing of the package object during internal cleanup
22148                 // of scan package
22149                 // We need to call parse directly here for no other reason than we need
22150                 // the new package in order to disable the old one [we use the information
22151                 // for some internal optimization to optionally create a new package setting
22152                 // object on replace]. However, we can't get the package from the scan
22153                 // because the scan modifies live structures and we need to remove the
22154                 // old [system] package from the system before a scan can be attempted.
22155                 // Once scan is indempotent we can remove this parse and use the package
22156                 // object we scanned, prior to adding it to package settings.
22157                 final PackageParser pp = new PackageParser();
22158                 pp.setSeparateProcesses(mSeparateProcesses);
22159                 pp.setDisplayMetrics(mMetrics);
22160                 pp.setCallback(mPackageParserCallback);
22161                 final PackageParser.Package tmpPkg;
22162                 try {
22163                     final int parseFlags = mDefParseFlags
22164                             | PackageParser.PARSE_MUST_BE_APK
22165                             | PackageParser.PARSE_IS_SYSTEM
22166                             | PackageParser.PARSE_IS_SYSTEM_DIR;
22167                     tmpPkg = pp.parsePackage(codePath, parseFlags);
22168                 } catch (PackageParserException e) {
22169                     Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
22170                     return;
22171                 }
22172                 synchronized (mInstallLock) {
22173                     // Disable the stub and remove any package entries
22174                     removePackageLI(deletedPkg, true);
22175                     synchronized (mPackages) {
22176                         disableSystemPackageLPw(deletedPkg, tmpPkg);
22177                     }
22178                     final PackageParser.Package newPkg;
22179                     try (PackageFreezer freezer =
22180                             freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
22181                         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
22182                                 | PackageParser.PARSE_ENFORCE_CODE;
22183                         newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
22184                                 0 /*currentTime*/, null /*user*/);
22185                         prepareAppDataAfterInstallLIF(newPkg);
22186                         synchronized (mPackages) {
22187                             try {
22188                                 updateSharedLibrariesLPr(newPkg, null);
22189                             } catch (PackageManagerException e) {
22190                                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
22191                             }
22192                             updatePermissionsLPw(newPkg.packageName, newPkg,
22193                                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
22194                             mSettings.writeLPr();
22195                         }
22196                     } catch (PackageManagerException e) {
22197                         // Whoops! Something went wrong; try to roll back to the stub
22198                         Slog.w(TAG, "Failed to install compressed system package:"
22199                                 + pkgSetting.name, e);
22200                         // Remove the failed install
22201                         removeCodePathLI(codePath);
22202 
22203                         // Install the system package
22204                         try (PackageFreezer freezer =
22205                                 freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
22206                             synchronized (mPackages) {
22207                                 // NOTE: The system package always needs to be enabled; even
22208                                 // if it's for a compressed stub. If we don't, installing the
22209                                 // system package fails during scan [scanning checks the disabled
22210                                 // packages]. We will reverse this later, after we've "installed"
22211                                 // the stub.
22212                                 // This leaves us in a fragile state; the stub should never be
22213                                 // enabled, so, cross your fingers and hope nothing goes wrong
22214                                 // until we can disable the package later.
22215                                 enableSystemPackageLPw(deletedPkg);
22216                             }
22217                             installPackageFromSystemLIF(new File(deletedPkg.codePath),
22218                                     false /*isPrivileged*/, null /*allUserHandles*/,
22219                                     null /*origUserHandles*/, null /*origPermissionsState*/,
22220                                     true /*writeSettings*/);
22221                         } catch (PackageManagerException pme) {
22222                             Slog.w(TAG, "Failed to restore system package:"
22223                                     + deletedPkg.packageName, pme);
22224                         } finally {
22225                             synchronized (mPackages) {
22226                                 mSettings.disableSystemPackageLPw(
22227                                         deletedPkg.packageName, true /*replaced*/);
22228                                 mSettings.writeLPr();
22229                             }
22230                         }
22231                         return;
22232                     }
22233                     clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
22234                             | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22235                     clearAppProfilesLIF(newPkg, UserHandle.USER_ALL);
22236                     mDexManager.notifyPackageUpdated(newPkg.packageName,
22237                             newPkg.baseCodePath, newPkg.splitCodePaths);
22238                 }
22239             }
22240             if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
22241                 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
22242                 // Don't care about who enables an app.
22243                 callingPackage = null;
22244             }
22245             synchronized (mPackages) {
22246                 pkgSetting.setEnabled(newState, userId, callingPackage);
22247             }
22248         } else {
22249             synchronized (mPackages) {
22250                 // We're dealing with a component level state change
22251                 // First, verify that this is a valid class name.
22252                 PackageParser.Package pkg = pkgSetting.pkg;
22253                 if (pkg == null || !pkg.hasComponentClassName(className)) {
22254                     if (pkg != null &&
22255                             pkg.applicationInfo.targetSdkVersion >=
22256                                     Build.VERSION_CODES.JELLY_BEAN) {
22257                         throw new IllegalArgumentException("Component class " + className
22258                                 + " does not exist in " + packageName);
22259                     } else {
22260                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
22261                                 + className + " does not exist in " + packageName);
22262                     }
22263                 }
22264                 switch (newState) {
22265                     case COMPONENT_ENABLED_STATE_ENABLED:
22266                         if (!pkgSetting.enableComponentLPw(className, userId)) {
22267                             return;
22268                         }
22269                         break;
22270                     case COMPONENT_ENABLED_STATE_DISABLED:
22271                         if (!pkgSetting.disableComponentLPw(className, userId)) {
22272                             return;
22273                         }
22274                         break;
22275                     case COMPONENT_ENABLED_STATE_DEFAULT:
22276                         if (!pkgSetting.restoreComponentLPw(className, userId)) {
22277                             return;
22278                         }
22279                         break;
22280                     default:
22281                         Slog.e(TAG, "Invalid new component state: " + newState);
22282                         return;
22283                 }
22284             }
22285         }
22286         synchronized (mPackages) {
22287             scheduleWritePackageRestrictionsLocked(userId);
22288             updateSequenceNumberLP(pkgSetting, new int[] { userId });
22289             final long callingId = Binder.clearCallingIdentity();
22290             try {
22291                 updateInstantAppInstallerLocked(packageName);
22292             } finally {
22293                 Binder.restoreCallingIdentity(callingId);
22294             }
22295             components = mPendingBroadcasts.get(userId, packageName);
22296             final boolean newPackage = components == null;
22297             if (newPackage) {
22298                 components = new ArrayList<String>();
22299             }
22300             if (!components.contains(componentName)) {
22301                 components.add(componentName);
22302             }
22303             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
22304                 sendNow = true;
22305                 // Purge entry from pending broadcast list if another one exists already
22306                 // since we are sending one right away.
22307                 mPendingBroadcasts.remove(userId, packageName);
22308             } else {
22309                 if (newPackage) {
22310                     mPendingBroadcasts.put(userId, packageName, components);
22311                 }
22312                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
22313                     // Schedule a message
22314                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
22315                 }
22316             }
22317         }
22318 
22319         long callingId = Binder.clearCallingIdentity();
22320         try {
22321             if (sendNow) {
22322                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
22323                 sendPackageChangedBroadcast(packageName,
22324                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
22325             }
22326         } finally {
22327             Binder.restoreCallingIdentity(callingId);
22328         }
22329     }
22330 
22331     @Override
flushPackageRestrictionsAsUser(int userId)22332     public void flushPackageRestrictionsAsUser(int userId) {
22333         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22334             return;
22335         }
22336         if (!sUserManager.exists(userId)) {
22337             return;
22338         }
22339         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
22340                 false /* checkShell */, "flushPackageRestrictions");
22341         synchronized (mPackages) {
22342             mSettings.writePackageRestrictionsLPr(userId);
22343             mDirtyUsers.remove(userId);
22344             if (mDirtyUsers.isEmpty()) {
22345                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
22346             }
22347         }
22348     }
22349 
sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)22350     private void sendPackageChangedBroadcast(String packageName,
22351             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
22352         if (DEBUG_INSTALL)
22353             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
22354                     + componentNames);
22355         Bundle extras = new Bundle(4);
22356         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
22357         String nameList[] = new String[componentNames.size()];
22358         componentNames.toArray(nameList);
22359         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
22360         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
22361         extras.putInt(Intent.EXTRA_UID, packageUid);
22362         // If this is not reporting a change of the overall package, then only send it
22363         // to registered receivers.  We don't want to launch a swath of apps for every
22364         // little component state change.
22365         final int flags = !componentNames.contains(packageName)
22366                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
22367         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
22368                 new int[] {UserHandle.getUserId(packageUid)});
22369     }
22370 
22371     @Override
setPackageStoppedState(String packageName, boolean stopped, int userId)22372     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
22373         if (!sUserManager.exists(userId)) return;
22374         final int callingUid = Binder.getCallingUid();
22375         if (getInstantAppPackageName(callingUid) != null) {
22376             return;
22377         }
22378         final int permission = mContext.checkCallingOrSelfPermission(
22379                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
22380         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
22381         enforceCrossUserPermission(callingUid, userId,
22382                 true /* requireFullPermission */, true /* checkShell */, "stop package");
22383         // writer
22384         synchronized (mPackages) {
22385             final PackageSetting ps = mSettings.mPackages.get(packageName);
22386             if (!filterAppAccessLPr(ps, callingUid, userId)
22387                     && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
22388                             allowedByPermission, callingUid, userId)) {
22389                 scheduleWritePackageRestrictionsLocked(userId);
22390             }
22391         }
22392     }
22393 
22394     @Override
getInstallerPackageName(String packageName)22395     public String getInstallerPackageName(String packageName) {
22396         final int callingUid = Binder.getCallingUid();
22397         if (getInstantAppPackageName(callingUid) != null) {
22398             return null;
22399         }
22400         // reader
22401         synchronized (mPackages) {
22402             final PackageSetting ps = mSettings.mPackages.get(packageName);
22403             if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
22404                 return null;
22405             }
22406             return mSettings.getInstallerPackageNameLPr(packageName);
22407         }
22408     }
22409 
isOrphaned(String packageName)22410     public boolean isOrphaned(String packageName) {
22411         // reader
22412         synchronized (mPackages) {
22413             return mSettings.isOrphaned(packageName);
22414         }
22415     }
22416 
22417     @Override
getApplicationEnabledSetting(String packageName, int userId)22418     public int getApplicationEnabledSetting(String packageName, int userId) {
22419         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22420         int callingUid = Binder.getCallingUid();
22421         enforceCrossUserPermission(callingUid, userId,
22422                 false /* requireFullPermission */, false /* checkShell */, "get enabled");
22423         // reader
22424         synchronized (mPackages) {
22425             if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
22426                 return COMPONENT_ENABLED_STATE_DISABLED;
22427             }
22428             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
22429         }
22430     }
22431 
22432     @Override
getComponentEnabledSetting(ComponentName component, int userId)22433     public int getComponentEnabledSetting(ComponentName component, int userId) {
22434         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22435         int callingUid = Binder.getCallingUid();
22436         enforceCrossUserPermission(callingUid, userId,
22437                 false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
22438         synchronized (mPackages) {
22439             if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
22440                     component, TYPE_UNKNOWN, userId)) {
22441                 return COMPONENT_ENABLED_STATE_DISABLED;
22442             }
22443             return mSettings.getComponentEnabledSettingLPr(component, userId);
22444         }
22445     }
22446 
22447     @Override
enterSafeMode()22448     public void enterSafeMode() {
22449         enforceSystemOrRoot("Only the system can request entering safe mode");
22450 
22451         if (!mSystemReady) {
22452             mSafeMode = true;
22453         }
22454     }
22455 
22456     @Override
systemReady()22457     public void systemReady() {
22458         enforceSystemOrRoot("Only the system can claim the system is ready");
22459 
22460         mSystemReady = true;
22461         final ContentResolver resolver = mContext.getContentResolver();
22462         ContentObserver co = new ContentObserver(mHandler) {
22463             @Override
22464             public void onChange(boolean selfChange) {
22465                 mEphemeralAppsDisabled =
22466                         (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
22467                                 (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
22468             }
22469         };
22470         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22471                         .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
22472                 false, co, UserHandle.USER_SYSTEM);
22473         mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22474                         .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
22475         co.onChange(true);
22476 
22477         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
22478         // disabled after already being started.
22479         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
22480                 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
22481 
22482         // Read the compatibilty setting when the system is ready.
22483         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
22484                 mContext.getContentResolver(),
22485                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
22486         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
22487         if (DEBUG_SETTINGS) {
22488             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
22489         }
22490 
22491         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
22492 
22493         synchronized (mPackages) {
22494             // Verify that all of the preferred activity components actually
22495             // exist.  It is possible for applications to be updated and at
22496             // that point remove a previously declared activity component that
22497             // had been set as a preferred activity.  We try to clean this up
22498             // the next time we encounter that preferred activity, but it is
22499             // possible for the user flow to never be able to return to that
22500             // situation so here we do a sanity check to make sure we haven't
22501             // left any junk around.
22502             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
22503             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22504                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22505                 removed.clear();
22506                 for (PreferredActivity pa : pir.filterSet()) {
22507                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
22508                         removed.add(pa);
22509                     }
22510                 }
22511                 if (removed.size() > 0) {
22512                     for (int r=0; r<removed.size(); r++) {
22513                         PreferredActivity pa = removed.get(r);
22514                         Slog.w(TAG, "Removing dangling preferred activity: "
22515                                 + pa.mPref.mComponent);
22516                         pir.removeFilter(pa);
22517                     }
22518                     mSettings.writePackageRestrictionsLPr(
22519                             mSettings.mPreferredActivities.keyAt(i));
22520                 }
22521             }
22522 
22523             for (int userId : UserManagerService.getInstance().getUserIds()) {
22524                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
22525                     grantPermissionsUserIds = ArrayUtils.appendInt(
22526                             grantPermissionsUserIds, userId);
22527                 }
22528             }
22529         }
22530         sUserManager.systemReady();
22531 
22532         // If we upgraded grant all default permissions before kicking off.
22533         for (int userId : grantPermissionsUserIds) {
22534             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22535         }
22536 
22537         // If we did not grant default permissions, we preload from this the
22538         // default permission exceptions lazily to ensure we don't hit the
22539         // disk on a new user creation.
22540         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
22541             mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
22542         }
22543 
22544         // Kick off any messages waiting for system ready
22545         if (mPostSystemReadyMessages != null) {
22546             for (Message msg : mPostSystemReadyMessages) {
22547                 msg.sendToTarget();
22548             }
22549             mPostSystemReadyMessages = null;
22550         }
22551 
22552         // Watch for external volumes that come and go over time
22553         final StorageManager storage = mContext.getSystemService(StorageManager.class);
22554         storage.registerListener(mStorageListener);
22555 
22556         mInstallerService.systemReady();
22557         mPackageDexOptimizer.systemReady();
22558 
22559         StorageManagerInternal StorageManagerInternal = LocalServices.getService(
22560                 StorageManagerInternal.class);
22561         StorageManagerInternal.addExternalStoragePolicy(
22562                 new StorageManagerInternal.ExternalStorageMountPolicy() {
22563             @Override
22564             public int getMountMode(int uid, String packageName) {
22565                 if (Process.isIsolated(uid)) {
22566                     return Zygote.MOUNT_EXTERNAL_NONE;
22567                 }
22568                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
22569                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
22570                 }
22571                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22572                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
22573                 }
22574                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22575                     return Zygote.MOUNT_EXTERNAL_READ;
22576                 }
22577                 return Zygote.MOUNT_EXTERNAL_WRITE;
22578             }
22579 
22580             @Override
22581             public boolean hasExternalStorage(int uid, String packageName) {
22582                 return true;
22583             }
22584         });
22585 
22586         // Now that we're mostly running, clean up stale users and apps
22587         sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
22588         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
22589 
22590         if (mPrivappPermissionsViolations != null) {
22591             Slog.wtf(TAG,"Signature|privileged permissions not in "
22592                     + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
22593             mPrivappPermissionsViolations = null;
22594         }
22595     }
22596 
waitForAppDataPrepared()22597     public void waitForAppDataPrepared() {
22598         if (mPrepareAppDataFuture == null) {
22599             return;
22600         }
22601         ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
22602         mPrepareAppDataFuture = null;
22603     }
22604 
22605     @Override
isSafeMode()22606     public boolean isSafeMode() {
22607         // allow instant applications
22608         return mSafeMode;
22609     }
22610 
22611     @Override
hasSystemUidErrors()22612     public boolean hasSystemUidErrors() {
22613         // allow instant applications
22614         return mHasSystemUidErrors;
22615     }
22616 
arrayToString(int[] array)22617     static String arrayToString(int[] array) {
22618         StringBuffer buf = new StringBuffer(128);
22619         buf.append('[');
22620         if (array != null) {
22621             for (int i=0; i<array.length; i++) {
22622                 if (i > 0) buf.append(", ");
22623                 buf.append(array[i]);
22624             }
22625         }
22626         buf.append(']');
22627         return buf.toString();
22628     }
22629 
22630     static class DumpState {
22631         public static final int DUMP_LIBS = 1 << 0;
22632         public static final int DUMP_FEATURES = 1 << 1;
22633         public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
22634         public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
22635         public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
22636         public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
22637         public static final int DUMP_PERMISSIONS = 1 << 6;
22638         public static final int DUMP_PACKAGES = 1 << 7;
22639         public static final int DUMP_SHARED_USERS = 1 << 8;
22640         public static final int DUMP_MESSAGES = 1 << 9;
22641         public static final int DUMP_PROVIDERS = 1 << 10;
22642         public static final int DUMP_VERIFIERS = 1 << 11;
22643         public static final int DUMP_PREFERRED = 1 << 12;
22644         public static final int DUMP_PREFERRED_XML = 1 << 13;
22645         public static final int DUMP_KEYSETS = 1 << 14;
22646         public static final int DUMP_VERSION = 1 << 15;
22647         public static final int DUMP_INSTALLS = 1 << 16;
22648         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
22649         public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
22650         public static final int DUMP_FROZEN = 1 << 19;
22651         public static final int DUMP_DEXOPT = 1 << 20;
22652         public static final int DUMP_COMPILER_STATS = 1 << 21;
22653         public static final int DUMP_CHANGES = 1 << 22;
22654         public static final int DUMP_VOLUMES = 1 << 23;
22655 
22656         public static final int OPTION_SHOW_FILTERS = 1 << 0;
22657 
22658         private int mTypes;
22659 
22660         private int mOptions;
22661 
22662         private boolean mTitlePrinted;
22663 
22664         private SharedUserSetting mSharedUser;
22665 
isDumping(int type)22666         public boolean isDumping(int type) {
22667             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
22668                 return true;
22669             }
22670 
22671             return (mTypes & type) != 0;
22672         }
22673 
setDump(int type)22674         public void setDump(int type) {
22675             mTypes |= type;
22676         }
22677 
isOptionEnabled(int option)22678         public boolean isOptionEnabled(int option) {
22679             return (mOptions & option) != 0;
22680         }
22681 
setOptionEnabled(int option)22682         public void setOptionEnabled(int option) {
22683             mOptions |= option;
22684         }
22685 
onTitlePrinted()22686         public boolean onTitlePrinted() {
22687             final boolean printed = mTitlePrinted;
22688             mTitlePrinted = true;
22689             return printed;
22690         }
22691 
getTitlePrinted()22692         public boolean getTitlePrinted() {
22693             return mTitlePrinted;
22694         }
22695 
setTitlePrinted(boolean enabled)22696         public void setTitlePrinted(boolean enabled) {
22697             mTitlePrinted = enabled;
22698         }
22699 
getSharedUser()22700         public SharedUserSetting getSharedUser() {
22701             return mSharedUser;
22702         }
22703 
setSharedUser(SharedUserSetting user)22704         public void setSharedUser(SharedUserSetting user) {
22705             mSharedUser = user;
22706         }
22707     }
22708 
22709     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)22710     public void onShellCommand(FileDescriptor in, FileDescriptor out,
22711             FileDescriptor err, String[] args, ShellCallback callback,
22712             ResultReceiver resultReceiver) {
22713         (new PackageManagerShellCommand(this)).exec(
22714                 this, in, out, err, args, callback, resultReceiver);
22715     }
22716 
22717     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)22718     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
22719         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
22720 
22721         DumpState dumpState = new DumpState();
22722         boolean fullPreferred = false;
22723         boolean checkin = false;
22724 
22725         String packageName = null;
22726         ArraySet<String> permissionNames = null;
22727 
22728         int opti = 0;
22729         while (opti < args.length) {
22730             String opt = args[opti];
22731             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
22732                 break;
22733             }
22734             opti++;
22735 
22736             if ("-a".equals(opt)) {
22737                 // Right now we only know how to print all.
22738             } else if ("-h".equals(opt)) {
22739                 pw.println("Package manager dump options:");
22740                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
22741                 pw.println("    --checkin: dump for a checkin");
22742                 pw.println("    -f: print details of intent filters");
22743                 pw.println("    -h: print this help");
22744                 pw.println("  cmd may be one of:");
22745                 pw.println("    l[ibraries]: list known shared libraries");
22746                 pw.println("    f[eatures]: list device features");
22747                 pw.println("    k[eysets]: print known keysets");
22748                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
22749                 pw.println("    perm[issions]: dump permissions");
22750                 pw.println("    permission [name ...]: dump declaration and use of given permission");
22751                 pw.println("    pref[erred]: print preferred package settings");
22752                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
22753                 pw.println("    prov[iders]: dump content providers");
22754                 pw.println("    p[ackages]: dump installed packages");
22755                 pw.println("    s[hared-users]: dump shared user IDs");
22756                 pw.println("    m[essages]: print collected runtime messages");
22757                 pw.println("    v[erifiers]: print package verifier info");
22758                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
22759                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
22760                 pw.println("    version: print database version info");
22761                 pw.println("    write: write current settings now");
22762                 pw.println("    installs: details about install sessions");
22763                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
22764                 pw.println("    dexopt: dump dexopt state");
22765                 pw.println("    compiler-stats: dump compiler statistics");
22766                 pw.println("    enabled-overlays: dump list of enabled overlay packages");
22767                 pw.println("    <package.name>: info about given package");
22768                 return;
22769             } else if ("--checkin".equals(opt)) {
22770                 checkin = true;
22771             } else if ("-f".equals(opt)) {
22772                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22773             } else if ("--proto".equals(opt)) {
22774                 dumpProto(fd);
22775                 return;
22776             } else {
22777                 pw.println("Unknown argument: " + opt + "; use -h for help");
22778             }
22779         }
22780 
22781         // Is the caller requesting to dump a particular piece of data?
22782         if (opti < args.length) {
22783             String cmd = args[opti];
22784             opti++;
22785             // Is this a package name?
22786             if ("android".equals(cmd) || cmd.contains(".")) {
22787                 packageName = cmd;
22788                 // When dumping a single package, we always dump all of its
22789                 // filter information since the amount of data will be reasonable.
22790                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22791             } else if ("check-permission".equals(cmd)) {
22792                 if (opti >= args.length) {
22793                     pw.println("Error: check-permission missing permission argument");
22794                     return;
22795                 }
22796                 String perm = args[opti];
22797                 opti++;
22798                 if (opti >= args.length) {
22799                     pw.println("Error: check-permission missing package argument");
22800                     return;
22801                 }
22802 
22803                 String pkg = args[opti];
22804                 opti++;
22805                 int user = UserHandle.getUserId(Binder.getCallingUid());
22806                 if (opti < args.length) {
22807                     try {
22808                         user = Integer.parseInt(args[opti]);
22809                     } catch (NumberFormatException e) {
22810                         pw.println("Error: check-permission user argument is not a number: "
22811                                 + args[opti]);
22812                         return;
22813                     }
22814                 }
22815 
22816                 // Normalize package name to handle renamed packages and static libs
22817                 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
22818 
22819                 pw.println(checkPermission(perm, pkg, user));
22820                 return;
22821             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
22822                 dumpState.setDump(DumpState.DUMP_LIBS);
22823             } else if ("f".equals(cmd) || "features".equals(cmd)) {
22824                 dumpState.setDump(DumpState.DUMP_FEATURES);
22825             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
22826                 if (opti >= args.length) {
22827                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
22828                             | DumpState.DUMP_SERVICE_RESOLVERS
22829                             | DumpState.DUMP_RECEIVER_RESOLVERS
22830                             | DumpState.DUMP_CONTENT_RESOLVERS);
22831                 } else {
22832                     while (opti < args.length) {
22833                         String name = args[opti];
22834                         if ("a".equals(name) || "activity".equals(name)) {
22835                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
22836                         } else if ("s".equals(name) || "service".equals(name)) {
22837                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
22838                         } else if ("r".equals(name) || "receiver".equals(name)) {
22839                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
22840                         } else if ("c".equals(name) || "content".equals(name)) {
22841                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
22842                         } else {
22843                             pw.println("Error: unknown resolver table type: " + name);
22844                             return;
22845                         }
22846                         opti++;
22847                     }
22848                 }
22849             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
22850                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
22851             } else if ("permission".equals(cmd)) {
22852                 if (opti >= args.length) {
22853                     pw.println("Error: permission requires permission name");
22854                     return;
22855                 }
22856                 permissionNames = new ArraySet<>();
22857                 while (opti < args.length) {
22858                     permissionNames.add(args[opti]);
22859                     opti++;
22860                 }
22861                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
22862                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
22863             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
22864                 dumpState.setDump(DumpState.DUMP_PREFERRED);
22865             } else if ("preferred-xml".equals(cmd)) {
22866                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
22867                 if (opti < args.length && "--full".equals(args[opti])) {
22868                     fullPreferred = true;
22869                     opti++;
22870                 }
22871             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
22872                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
22873             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
22874                 dumpState.setDump(DumpState.DUMP_PACKAGES);
22875             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
22876                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
22877             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
22878                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
22879             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
22880                 dumpState.setDump(DumpState.DUMP_MESSAGES);
22881             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
22882                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
22883             } else if ("i".equals(cmd) || "ifv".equals(cmd)
22884                     || "intent-filter-verifiers".equals(cmd)) {
22885                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
22886             } else if ("version".equals(cmd)) {
22887                 dumpState.setDump(DumpState.DUMP_VERSION);
22888             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
22889                 dumpState.setDump(DumpState.DUMP_KEYSETS);
22890             } else if ("installs".equals(cmd)) {
22891                 dumpState.setDump(DumpState.DUMP_INSTALLS);
22892             } else if ("frozen".equals(cmd)) {
22893                 dumpState.setDump(DumpState.DUMP_FROZEN);
22894             } else if ("volumes".equals(cmd)) {
22895                 dumpState.setDump(DumpState.DUMP_VOLUMES);
22896             } else if ("dexopt".equals(cmd)) {
22897                 dumpState.setDump(DumpState.DUMP_DEXOPT);
22898             } else if ("compiler-stats".equals(cmd)) {
22899                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
22900             } else if ("changes".equals(cmd)) {
22901                 dumpState.setDump(DumpState.DUMP_CHANGES);
22902             } else if ("write".equals(cmd)) {
22903                 synchronized (mPackages) {
22904                     mSettings.writeLPr();
22905                     pw.println("Settings written.");
22906                     return;
22907                 }
22908             }
22909         }
22910 
22911         if (checkin) {
22912             pw.println("vers,1");
22913         }
22914 
22915         // reader
22916         synchronized (mPackages) {
22917             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
22918                 if (!checkin) {
22919                     if (dumpState.onTitlePrinted())
22920                         pw.println();
22921                     pw.println("Database versions:");
22922                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
22923                 }
22924             }
22925 
22926             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
22927                 if (!checkin) {
22928                     if (dumpState.onTitlePrinted())
22929                         pw.println();
22930                     pw.println("Verifiers:");
22931                     pw.print("  Required: ");
22932                     pw.print(mRequiredVerifierPackage);
22933                     pw.print(" (uid=");
22934                     pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22935                             UserHandle.USER_SYSTEM));
22936                     pw.println(")");
22937                 } else if (mRequiredVerifierPackage != null) {
22938                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
22939                     pw.print(",");
22940                     pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22941                             UserHandle.USER_SYSTEM));
22942                 }
22943             }
22944 
22945             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
22946                     packageName == null) {
22947                 if (mIntentFilterVerifierComponent != null) {
22948                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22949                     if (!checkin) {
22950                         if (dumpState.onTitlePrinted())
22951                             pw.println();
22952                         pw.println("Intent Filter Verifier:");
22953                         pw.print("  Using: ");
22954                         pw.print(verifierPackageName);
22955                         pw.print(" (uid=");
22956                         pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22957                                 UserHandle.USER_SYSTEM));
22958                         pw.println(")");
22959                     } else if (verifierPackageName != null) {
22960                         pw.print("ifv,"); pw.print(verifierPackageName);
22961                         pw.print(",");
22962                         pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22963                                 UserHandle.USER_SYSTEM));
22964                     }
22965                 } else {
22966                     pw.println();
22967                     pw.println("No Intent Filter Verifier available!");
22968                 }
22969             }
22970 
22971             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22972                 boolean printedHeader = false;
22973                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
22974                 while (it.hasNext()) {
22975                     String libName = it.next();
22976                     SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22977                     if (versionedLib == null) {
22978                         continue;
22979                     }
22980                     final int versionCount = versionedLib.size();
22981                     for (int i = 0; i < versionCount; i++) {
22982                         SharedLibraryEntry libEntry = versionedLib.valueAt(i);
22983                         if (!checkin) {
22984                             if (!printedHeader) {
22985                                 if (dumpState.onTitlePrinted())
22986                                     pw.println();
22987                                 pw.println("Libraries:");
22988                                 printedHeader = true;
22989                             }
22990                             pw.print("  ");
22991                         } else {
22992                             pw.print("lib,");
22993                         }
22994                         pw.print(libEntry.info.getName());
22995                         if (libEntry.info.isStatic()) {
22996                             pw.print(" version=" + libEntry.info.getVersion());
22997                         }
22998                         if (!checkin) {
22999                             pw.print(" -> ");
23000                         }
23001                         if (libEntry.path != null) {
23002                             pw.print(" (jar) ");
23003                             pw.print(libEntry.path);
23004                         } else {
23005                             pw.print(" (apk) ");
23006                             pw.print(libEntry.apk);
23007                         }
23008                         pw.println();
23009                     }
23010                 }
23011             }
23012 
23013             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
23014                 if (dumpState.onTitlePrinted())
23015                     pw.println();
23016                 if (!checkin) {
23017                     pw.println("Features:");
23018                 }
23019 
23020                 synchronized (mAvailableFeatures) {
23021                     for (FeatureInfo feat : mAvailableFeatures.values()) {
23022                         if (checkin) {
23023                             pw.print("feat,");
23024                             pw.print(feat.name);
23025                             pw.print(",");
23026                             pw.println(feat.version);
23027                         } else {
23028                             pw.print("  ");
23029                             pw.print(feat.name);
23030                             if (feat.version > 0) {
23031                                 pw.print(" version=");
23032                                 pw.print(feat.version);
23033                             }
23034                             pw.println();
23035                         }
23036                     }
23037                 }
23038             }
23039 
23040             if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
23041                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
23042                         : "Activity Resolver Table:", "  ", packageName,
23043                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
23044                     dumpState.setTitlePrinted(true);
23045                 }
23046             }
23047             if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
23048                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
23049                         : "Receiver Resolver Table:", "  ", packageName,
23050                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
23051                     dumpState.setTitlePrinted(true);
23052                 }
23053             }
23054             if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
23055                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
23056                         : "Service Resolver Table:", "  ", packageName,
23057                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
23058                     dumpState.setTitlePrinted(true);
23059                 }
23060             }
23061             if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
23062                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
23063                         : "Provider Resolver Table:", "  ", packageName,
23064                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
23065                     dumpState.setTitlePrinted(true);
23066                 }
23067             }
23068 
23069             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
23070                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
23071                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
23072                     int user = mSettings.mPreferredActivities.keyAt(i);
23073                     if (pir.dump(pw,
23074                             dumpState.getTitlePrinted()
23075                                 ? "\nPreferred Activities User " + user + ":"
23076                                 : "Preferred Activities User " + user + ":", "  ",
23077                             packageName, true, false)) {
23078                         dumpState.setTitlePrinted(true);
23079                     }
23080                 }
23081             }
23082 
23083             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
23084                 pw.flush();
23085                 FileOutputStream fout = new FileOutputStream(fd);
23086                 BufferedOutputStream str = new BufferedOutputStream(fout);
23087                 XmlSerializer serializer = new FastXmlSerializer();
23088                 try {
23089                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
23090                     serializer.startDocument(null, true);
23091                     serializer.setFeature(
23092                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
23093                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
23094                     serializer.endDocument();
23095                     serializer.flush();
23096                 } catch (IllegalArgumentException e) {
23097                     pw.println("Failed writing: " + e);
23098                 } catch (IllegalStateException e) {
23099                     pw.println("Failed writing: " + e);
23100                 } catch (IOException e) {
23101                     pw.println("Failed writing: " + e);
23102                 }
23103             }
23104 
23105             if (!checkin
23106                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
23107                     && packageName == null) {
23108                 pw.println();
23109                 int count = mSettings.mPackages.size();
23110                 if (count == 0) {
23111                     pw.println("No applications!");
23112                     pw.println();
23113                 } else {
23114                     final String prefix = "  ";
23115                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
23116                     if (allPackageSettings.size() == 0) {
23117                         pw.println("No domain preferred apps!");
23118                         pw.println();
23119                     } else {
23120                         pw.println("App verification status:");
23121                         pw.println();
23122                         count = 0;
23123                         for (PackageSetting ps : allPackageSettings) {
23124                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
23125                             if (ivi == null || ivi.getPackageName() == null) continue;
23126                             pw.println(prefix + "Package: " + ivi.getPackageName());
23127                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
23128                             pw.println(prefix + "Status:  " + ivi.getStatusString());
23129                             pw.println();
23130                             count++;
23131                         }
23132                         if (count == 0) {
23133                             pw.println(prefix + "No app verification established.");
23134                             pw.println();
23135                         }
23136                         for (int userId : sUserManager.getUserIds()) {
23137                             pw.println("App linkages for user " + userId + ":");
23138                             pw.println();
23139                             count = 0;
23140                             for (PackageSetting ps : allPackageSettings) {
23141                                 final long status = ps.getDomainVerificationStatusForUser(userId);
23142                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
23143                                         && !DEBUG_DOMAIN_VERIFICATION) {
23144                                     continue;
23145                                 }
23146                                 pw.println(prefix + "Package: " + ps.name);
23147                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
23148                                 String statusStr = IntentFilterVerificationInfo.
23149                                         getStatusStringFromValue(status);
23150                                 pw.println(prefix + "Status:  " + statusStr);
23151                                 pw.println();
23152                                 count++;
23153                             }
23154                             if (count == 0) {
23155                                 pw.println(prefix + "No configured app linkages.");
23156                                 pw.println();
23157                             }
23158                         }
23159                     }
23160                 }
23161             }
23162 
23163             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
23164                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
23165                 if (packageName == null && permissionNames == null) {
23166                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
23167                         if (iperm == 0) {
23168                             if (dumpState.onTitlePrinted())
23169                                 pw.println();
23170                             pw.println("AppOp Permissions:");
23171                         }
23172                         pw.print("  AppOp Permission ");
23173                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
23174                         pw.println(":");
23175                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
23176                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
23177                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
23178                         }
23179                     }
23180                 }
23181             }
23182 
23183             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
23184                 boolean printedSomething = false;
23185                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
23186                     if (packageName != null && !packageName.equals(p.info.packageName)) {
23187                         continue;
23188                     }
23189                     if (!printedSomething) {
23190                         if (dumpState.onTitlePrinted())
23191                             pw.println();
23192                         pw.println("Registered ContentProviders:");
23193                         printedSomething = true;
23194                     }
23195                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
23196                     pw.print("    "); pw.println(p.toString());
23197                 }
23198                 printedSomething = false;
23199                 for (Map.Entry<String, PackageParser.Provider> entry :
23200                         mProvidersByAuthority.entrySet()) {
23201                     PackageParser.Provider p = entry.getValue();
23202                     if (packageName != null && !packageName.equals(p.info.packageName)) {
23203                         continue;
23204                     }
23205                     if (!printedSomething) {
23206                         if (dumpState.onTitlePrinted())
23207                             pw.println();
23208                         pw.println("ContentProvider Authorities:");
23209                         printedSomething = true;
23210                     }
23211                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
23212                     pw.print("    "); pw.println(p.toString());
23213                     if (p.info != null && p.info.applicationInfo != null) {
23214                         final String appInfo = p.info.applicationInfo.toString();
23215                         pw.print("      applicationInfo="); pw.println(appInfo);
23216                     }
23217                 }
23218             }
23219 
23220             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
23221                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
23222             }
23223 
23224             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
23225                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
23226             }
23227 
23228             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
23229                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
23230             }
23231 
23232             if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
23233                 if (dumpState.onTitlePrinted()) pw.println();
23234                 pw.println("Package Changes:");
23235                 pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
23236                 final int K = mChangedPackages.size();
23237                 for (int i = 0; i < K; i++) {
23238                     final SparseArray<String> changes = mChangedPackages.valueAt(i);
23239                     pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
23240                     final int N = changes.size();
23241                     if (N == 0) {
23242                         pw.print("    "); pw.println("No packages changed");
23243                     } else {
23244                         for (int j = 0; j < N; j++) {
23245                             final String pkgName = changes.valueAt(j);
23246                             final int sequenceNumber = changes.keyAt(j);
23247                             pw.print("    ");
23248                             pw.print("seq=");
23249                             pw.print(sequenceNumber);
23250                             pw.print(", package=");
23251                             pw.println(pkgName);
23252                         }
23253                     }
23254                 }
23255             }
23256 
23257             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
23258                 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
23259             }
23260 
23261             if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
23262                 // XXX should handle packageName != null by dumping only install data that
23263                 // the given package is involved with.
23264                 if (dumpState.onTitlePrinted()) pw.println();
23265 
23266                 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23267                 ipw.println();
23268                 ipw.println("Frozen packages:");
23269                 ipw.increaseIndent();
23270                 if (mFrozenPackages.size() == 0) {
23271                     ipw.println("(none)");
23272                 } else {
23273                     for (int i = 0; i < mFrozenPackages.size(); i++) {
23274                         ipw.println(mFrozenPackages.valueAt(i));
23275                     }
23276                 }
23277                 ipw.decreaseIndent();
23278             }
23279 
23280             if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
23281                 if (dumpState.onTitlePrinted()) pw.println();
23282 
23283                 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23284                 ipw.println();
23285                 ipw.println("Loaded volumes:");
23286                 ipw.increaseIndent();
23287                 if (mLoadedVolumes.size() == 0) {
23288                     ipw.println("(none)");
23289                 } else {
23290                     for (int i = 0; i < mLoadedVolumes.size(); i++) {
23291                         ipw.println(mLoadedVolumes.valueAt(i));
23292                     }
23293                 }
23294                 ipw.decreaseIndent();
23295             }
23296 
23297             if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
23298                 if (dumpState.onTitlePrinted()) pw.println();
23299                 dumpDexoptStateLPr(pw, packageName);
23300             }
23301 
23302             if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
23303                 if (dumpState.onTitlePrinted()) pw.println();
23304                 dumpCompilerStatsLPr(pw, packageName);
23305             }
23306 
23307             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
23308                 if (dumpState.onTitlePrinted()) pw.println();
23309                 mSettings.dumpReadMessagesLPr(pw, dumpState);
23310 
23311                 pw.println();
23312                 pw.println("Package warning messages:");
23313                 BufferedReader in = null;
23314                 String line = null;
23315                 try {
23316                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23317                     while ((line = in.readLine()) != null) {
23318                         if (line.contains("ignored: updated version")) continue;
23319                         pw.println(line);
23320                     }
23321                 } catch (IOException ignored) {
23322                 } finally {
23323                     IoUtils.closeQuietly(in);
23324                 }
23325             }
23326 
23327             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
23328                 BufferedReader in = null;
23329                 String line = null;
23330                 try {
23331                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23332                     while ((line = in.readLine()) != null) {
23333                         if (line.contains("ignored: updated version")) continue;
23334                         pw.print("msg,");
23335                         pw.println(line);
23336                     }
23337                 } catch (IOException ignored) {
23338                 } finally {
23339                     IoUtils.closeQuietly(in);
23340                 }
23341             }
23342         }
23343 
23344         // PackageInstaller should be called outside of mPackages lock
23345         if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
23346             // XXX should handle packageName != null by dumping only install data that
23347             // the given package is involved with.
23348             if (dumpState.onTitlePrinted()) pw.println();
23349             mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
23350         }
23351     }
23352 
dumpProto(FileDescriptor fd)23353     private void dumpProto(FileDescriptor fd) {
23354         final ProtoOutputStream proto = new ProtoOutputStream(fd);
23355 
23356         synchronized (mPackages) {
23357             final long requiredVerifierPackageToken =
23358                     proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
23359             proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
23360             proto.write(
23361                     PackageServiceDumpProto.PackageShortProto.UID,
23362                     getPackageUid(
23363                             mRequiredVerifierPackage,
23364                             MATCH_DEBUG_TRIAGED_MISSING,
23365                             UserHandle.USER_SYSTEM));
23366             proto.end(requiredVerifierPackageToken);
23367 
23368             if (mIntentFilterVerifierComponent != null) {
23369                 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
23370                 final long verifierPackageToken =
23371                         proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
23372                 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
23373                 proto.write(
23374                         PackageServiceDumpProto.PackageShortProto.UID,
23375                         getPackageUid(
23376                                 verifierPackageName,
23377                                 MATCH_DEBUG_TRIAGED_MISSING,
23378                                 UserHandle.USER_SYSTEM));
23379                 proto.end(verifierPackageToken);
23380             }
23381 
23382             dumpSharedLibrariesProto(proto);
23383             dumpFeaturesProto(proto);
23384             mSettings.dumpPackagesProto(proto);
23385             mSettings.dumpSharedUsersProto(proto);
23386             dumpMessagesProto(proto);
23387         }
23388         proto.flush();
23389     }
23390 
dumpMessagesProto(ProtoOutputStream proto)23391     private void dumpMessagesProto(ProtoOutputStream proto) {
23392         BufferedReader in = null;
23393         String line = null;
23394         try {
23395             in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23396             while ((line = in.readLine()) != null) {
23397                 if (line.contains("ignored: updated version")) continue;
23398                 proto.write(PackageServiceDumpProto.MESSAGES, line);
23399             }
23400         } catch (IOException ignored) {
23401         } finally {
23402             IoUtils.closeQuietly(in);
23403         }
23404     }
23405 
dumpFeaturesProto(ProtoOutputStream proto)23406     private void dumpFeaturesProto(ProtoOutputStream proto) {
23407         synchronized (mAvailableFeatures) {
23408             final int count = mAvailableFeatures.size();
23409             for (int i = 0; i < count; i++) {
23410                 final FeatureInfo feat = mAvailableFeatures.valueAt(i);
23411                 final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
23412                 proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
23413                 proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
23414                 proto.end(featureToken);
23415             }
23416         }
23417     }
23418 
dumpSharedLibrariesProto(ProtoOutputStream proto)23419     private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
23420         final int count = mSharedLibraries.size();
23421         for (int i = 0; i < count; i++) {
23422             final String libName = mSharedLibraries.keyAt(i);
23423             SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
23424             if (versionedLib == null) {
23425                 continue;
23426             }
23427             final int versionCount = versionedLib.size();
23428             for (int j = 0; j < versionCount; j++) {
23429                 final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
23430                 final long sharedLibraryToken =
23431                         proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
23432                 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
23433                 final boolean isJar = (libEntry.path != null);
23434                 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
23435                 if (isJar) {
23436                     proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
23437                 } else {
23438                     proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
23439                 }
23440                 proto.end(sharedLibraryToken);
23441             }
23442         }
23443     }
23444 
dumpDexoptStateLPr(PrintWriter pw, String packageName)23445     private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
23446         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23447         ipw.println();
23448         ipw.println("Dexopt state:");
23449         ipw.increaseIndent();
23450         Collection<PackageParser.Package> packages = null;
23451         if (packageName != null) {
23452             PackageParser.Package targetPackage = mPackages.get(packageName);
23453             if (targetPackage != null) {
23454                 packages = Collections.singletonList(targetPackage);
23455             } else {
23456                 ipw.println("Unable to find package: " + packageName);
23457                 return;
23458             }
23459         } else {
23460             packages = mPackages.values();
23461         }
23462 
23463         for (PackageParser.Package pkg : packages) {
23464             ipw.println("[" + pkg.packageName + "]");
23465             ipw.increaseIndent();
23466             mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
23467                     mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
23468             ipw.decreaseIndent();
23469         }
23470     }
23471 
dumpCompilerStatsLPr(PrintWriter pw, String packageName)23472     private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
23473         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23474         ipw.println();
23475         ipw.println("Compiler stats:");
23476         ipw.increaseIndent();
23477         Collection<PackageParser.Package> packages = null;
23478         if (packageName != null) {
23479             PackageParser.Package targetPackage = mPackages.get(packageName);
23480             if (targetPackage != null) {
23481                 packages = Collections.singletonList(targetPackage);
23482             } else {
23483                 ipw.println("Unable to find package: " + packageName);
23484                 return;
23485             }
23486         } else {
23487             packages = mPackages.values();
23488         }
23489 
23490         for (PackageParser.Package pkg : packages) {
23491             ipw.println("[" + pkg.packageName + "]");
23492             ipw.increaseIndent();
23493 
23494             CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
23495             if (stats == null) {
23496                 ipw.println("(No recorded stats)");
23497             } else {
23498                 stats.dump(ipw);
23499             }
23500             ipw.decreaseIndent();
23501         }
23502     }
23503 
dumpDomainString(String packageName)23504     private String dumpDomainString(String packageName) {
23505         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
23506                 .getList();
23507         List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
23508 
23509         ArraySet<String> result = new ArraySet<>();
23510         if (iviList.size() > 0) {
23511             for (IntentFilterVerificationInfo ivi : iviList) {
23512                 for (String host : ivi.getDomains()) {
23513                     result.add(host);
23514                 }
23515             }
23516         }
23517         if (filters != null && filters.size() > 0) {
23518             for (IntentFilter filter : filters) {
23519                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
23520                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
23521                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
23522                     result.addAll(filter.getHostsList());
23523                 }
23524             }
23525         }
23526 
23527         StringBuilder sb = new StringBuilder(result.size() * 16);
23528         for (String domain : result) {
23529             if (sb.length() > 0) sb.append(" ");
23530             sb.append(domain);
23531         }
23532         return sb.toString();
23533     }
23534 
23535     // ------- apps on sdcard specific code -------
23536     static final boolean DEBUG_SD_INSTALL = false;
23537 
23538     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
23539 
23540     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
23541 
23542     private boolean mMediaMounted = false;
23543 
getEncryptKey()23544     static String getEncryptKey() {
23545         try {
23546             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
23547                     SD_ENCRYPTION_KEYSTORE_NAME);
23548             if (sdEncKey == null) {
23549                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
23550                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
23551                 if (sdEncKey == null) {
23552                     Slog.e(TAG, "Failed to create encryption keys");
23553                     return null;
23554                 }
23555             }
23556             return sdEncKey;
23557         } catch (NoSuchAlgorithmException nsae) {
23558             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
23559             return null;
23560         } catch (IOException ioe) {
23561             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
23562             return null;
23563         }
23564     }
23565 
23566     /*
23567      * Update media status on PackageManager.
23568      */
23569     @Override
updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)23570     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
23571         enforceSystemOrRoot("Media status can only be updated by the system");
23572         // reader; this apparently protects mMediaMounted, but should probably
23573         // be a different lock in that case.
23574         synchronized (mPackages) {
23575             Log.i(TAG, "Updating external media status from "
23576                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
23577                     + (mediaStatus ? "mounted" : "unmounted"));
23578             if (DEBUG_SD_INSTALL)
23579                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
23580                         + ", mMediaMounted=" + mMediaMounted);
23581             if (mediaStatus == mMediaMounted) {
23582                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
23583                         : 0, -1);
23584                 mHandler.sendMessage(msg);
23585                 return;
23586             }
23587             mMediaMounted = mediaStatus;
23588         }
23589         // Queue up an async operation since the package installation may take a
23590         // little while.
23591         mHandler.post(new Runnable() {
23592             public void run() {
23593                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
23594             }
23595         });
23596     }
23597 
23598     /**
23599      * Called by StorageManagerService when the initial ASECs to scan are available.
23600      * Should block until all the ASEC containers are finished being scanned.
23601      */
scanAvailableAsecs()23602     public void scanAvailableAsecs() {
23603         updateExternalMediaStatusInner(true, false, false);
23604     }
23605 
23606     /*
23607      * Collect information of applications on external media, map them against
23608      * existing containers and update information based on current mount status.
23609      * Please note that we always have to report status if reportStatus has been
23610      * set to true especially when unloading packages.
23611      */
updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)23612     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
23613             boolean externalStorage) {
23614         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
23615         int[] uidArr = EmptyArray.INT;
23616 
23617         final String[] list = PackageHelper.getSecureContainerList();
23618         if (ArrayUtils.isEmpty(list)) {
23619             Log.i(TAG, "No secure containers found");
23620         } else {
23621             // Process list of secure containers and categorize them
23622             // as active or stale based on their package internal state.
23623 
23624             // reader
23625             synchronized (mPackages) {
23626                 for (String cid : list) {
23627                     // Leave stages untouched for now; installer service owns them
23628                     if (PackageInstallerService.isStageName(cid)) continue;
23629 
23630                     if (DEBUG_SD_INSTALL)
23631                         Log.i(TAG, "Processing container " + cid);
23632                     String pkgName = getAsecPackageName(cid);
23633                     if (pkgName == null) {
23634                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
23635                         continue;
23636                     }
23637                     if (DEBUG_SD_INSTALL)
23638                         Log.i(TAG, "Looking for pkg : " + pkgName);
23639 
23640                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
23641                     if (ps == null) {
23642                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
23643                         continue;
23644                     }
23645 
23646                     /*
23647                      * Skip packages that are not external if we're unmounting
23648                      * external storage.
23649                      */
23650                     if (externalStorage && !isMounted && !isExternal(ps)) {
23651                         continue;
23652                     }
23653 
23654                     final AsecInstallArgs args = new AsecInstallArgs(cid,
23655                             getAppDexInstructionSets(ps), ps.isForwardLocked());
23656                     // The package status is changed only if the code path
23657                     // matches between settings and the container id.
23658                     if (ps.codePathString != null
23659                             && ps.codePathString.startsWith(args.getCodePath())) {
23660                         if (DEBUG_SD_INSTALL) {
23661                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
23662                                     + " at code path: " + ps.codePathString);
23663                         }
23664 
23665                         // We do have a valid package installed on sdcard
23666                         processCids.put(args, ps.codePathString);
23667                         final int uid = ps.appId;
23668                         if (uid != -1) {
23669                             uidArr = ArrayUtils.appendInt(uidArr, uid);
23670                         }
23671                     } else {
23672                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
23673                                 + ps.codePathString);
23674                     }
23675                 }
23676             }
23677 
23678             Arrays.sort(uidArr);
23679         }
23680 
23681         // Process packages with valid entries.
23682         if (isMounted) {
23683             if (DEBUG_SD_INSTALL)
23684                 Log.i(TAG, "Loading packages");
23685             loadMediaPackages(processCids, uidArr, externalStorage);
23686             startCleaningPackages();
23687             mInstallerService.onSecureContainersAvailable();
23688         } else {
23689             if (DEBUG_SD_INSTALL)
23690                 Log.i(TAG, "Unloading packages");
23691             unloadMediaPackages(processCids, uidArr, reportStatus);
23692         }
23693     }
23694 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver)23695     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23696             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
23697         final int size = infos.size();
23698         final String[] packageNames = new String[size];
23699         final int[] packageUids = new int[size];
23700         for (int i = 0; i < size; i++) {
23701             final ApplicationInfo info = infos.get(i);
23702             packageNames[i] = info.packageName;
23703             packageUids[i] = info.uid;
23704         }
23705         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
23706                 finishedReceiver);
23707     }
23708 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)23709     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23710             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23711         sendResourcesChangedBroadcast(mediaStatus, replacing,
23712                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
23713     }
23714 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver)23715     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23716             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23717         int size = pkgList.length;
23718         if (size > 0) {
23719             // Send broadcasts here
23720             Bundle extras = new Bundle();
23721             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
23722             if (uidArr != null) {
23723                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
23724             }
23725             if (replacing) {
23726                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
23727             }
23728             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
23729                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
23730             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
23731         }
23732     }
23733 
23734    /*
23735      * Look at potentially valid container ids from processCids If package
23736      * information doesn't match the one on record or package scanning fails,
23737      * the cid is added to list of removeCids. We currently don't delete stale
23738      * containers.
23739      */
loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, boolean externalStorage)23740     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
23741             boolean externalStorage) {
23742         ArrayList<String> pkgList = new ArrayList<String>();
23743         Set<AsecInstallArgs> keys = processCids.keySet();
23744 
23745         for (AsecInstallArgs args : keys) {
23746             String codePath = processCids.get(args);
23747             if (DEBUG_SD_INSTALL)
23748                 Log.i(TAG, "Loading container : " + args.cid);
23749             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
23750             try {
23751                 // Make sure there are no container errors first.
23752                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
23753                     Slog.e(TAG, "Failed to mount cid : " + args.cid
23754                             + " when installing from sdcard");
23755                     continue;
23756                 }
23757                 // Check code path here.
23758                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
23759                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
23760                             + " does not match one in settings " + codePath);
23761                     continue;
23762                 }
23763                 // Parse package
23764                 int parseFlags = mDefParseFlags;
23765                 if (args.isExternalAsec()) {
23766                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
23767                 }
23768                 if (args.isFwdLocked()) {
23769                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
23770                 }
23771 
23772                 synchronized (mInstallLock) {
23773                     PackageParser.Package pkg = null;
23774                     try {
23775                         // Sadly we don't know the package name yet to freeze it
23776                         pkg = scanPackageTracedLI(new File(codePath), parseFlags,
23777                                 SCAN_IGNORE_FROZEN, 0, null);
23778                     } catch (PackageManagerException e) {
23779                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
23780                     }
23781                     // Scan the package
23782                     if (pkg != null) {
23783                         /*
23784                          * TODO why is the lock being held? doPostInstall is
23785                          * called in other places without the lock. This needs
23786                          * to be straightened out.
23787                          */
23788                         // writer
23789                         synchronized (mPackages) {
23790                             retCode = PackageManager.INSTALL_SUCCEEDED;
23791                             pkgList.add(pkg.packageName);
23792                             // Post process args
23793                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
23794                                     pkg.applicationInfo.uid);
23795                         }
23796                     } else {
23797                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
23798                     }
23799                 }
23800 
23801             } finally {
23802                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
23803                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
23804                 }
23805             }
23806         }
23807         // writer
23808         synchronized (mPackages) {
23809             // If the platform SDK has changed since the last time we booted,
23810             // we need to re-grant app permission to catch any new ones that
23811             // appear. This is really a hack, and means that apps can in some
23812             // cases get permissions that the user didn't initially explicitly
23813             // allow... it would be nice to have some better way to handle
23814             // this situation.
23815             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
23816                     : mSettings.getInternalVersion();
23817             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
23818                     : StorageManager.UUID_PRIVATE_INTERNAL;
23819 
23820             int updateFlags = UPDATE_PERMISSIONS_ALL;
23821             if (ver.sdkVersion != mSdkVersion) {
23822                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23823                         + mSdkVersion + "; regranting permissions for external");
23824                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23825             }
23826             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23827 
23828             // Yay, everything is now upgraded
23829             ver.forceCurrent();
23830 
23831             // can downgrade to reader
23832             // Persist settings
23833             mSettings.writeLPr();
23834         }
23835         // Send a broadcast to let everyone know we are done processing
23836         if (pkgList.size() > 0) {
23837             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
23838         }
23839     }
23840 
23841    /*
23842      * Utility method to unload a list of specified containers
23843      */
unloadAllContainers(Set<AsecInstallArgs> cidArgs)23844     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
23845         // Just unmount all valid containers.
23846         for (AsecInstallArgs arg : cidArgs) {
23847             synchronized (mInstallLock) {
23848                 arg.doPostDeleteLI(false);
23849            }
23850        }
23851    }
23852 
23853     /*
23854      * Unload packages mounted on external media. This involves deleting package
23855      * data from internal structures, sending broadcasts about disabled packages,
23856      * gc'ing to free up references, unmounting all secure containers
23857      * corresponding to packages on external media, and posting a
23858      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
23859      * that we always have to post this message if status has been requested no
23860      * matter what.
23861      */
unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)23862     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
23863             final boolean reportStatus) {
23864         if (DEBUG_SD_INSTALL)
23865             Log.i(TAG, "unloading media packages");
23866         ArrayList<String> pkgList = new ArrayList<String>();
23867         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
23868         final Set<AsecInstallArgs> keys = processCids.keySet();
23869         for (AsecInstallArgs args : keys) {
23870             String pkgName = args.getPackageName();
23871             if (DEBUG_SD_INSTALL)
23872                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
23873             // Delete package internally
23874             PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23875             synchronized (mInstallLock) {
23876                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23877                 final boolean res;
23878                 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
23879                         "unloadMediaPackages")) {
23880                     res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
23881                             null);
23882                 }
23883                 if (res) {
23884                     pkgList.add(pkgName);
23885                 } else {
23886                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
23887                     failedList.add(args);
23888                 }
23889             }
23890         }
23891 
23892         // reader
23893         synchronized (mPackages) {
23894             // We didn't update the settings after removing each package;
23895             // write them now for all packages.
23896             mSettings.writeLPr();
23897         }
23898 
23899         // We have to absolutely send UPDATED_MEDIA_STATUS only
23900         // after confirming that all the receivers processed the ordered
23901         // broadcast when packages get disabled, force a gc to clean things up.
23902         // and unload all the containers.
23903         if (pkgList.size() > 0) {
23904             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
23905                     new IIntentReceiver.Stub() {
23906                 public void performReceive(Intent intent, int resultCode, String data,
23907                         Bundle extras, boolean ordered, boolean sticky,
23908                         int sendingUser) throws RemoteException {
23909                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
23910                             reportStatus ? 1 : 0, 1, keys);
23911                     mHandler.sendMessage(msg);
23912                 }
23913             });
23914         } else {
23915             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
23916                     keys);
23917             mHandler.sendMessage(msg);
23918         }
23919     }
23920 
loadPrivatePackages(final VolumeInfo vol)23921     private void loadPrivatePackages(final VolumeInfo vol) {
23922         mHandler.post(new Runnable() {
23923             @Override
23924             public void run() {
23925                 loadPrivatePackagesInner(vol);
23926             }
23927         });
23928     }
23929 
loadPrivatePackagesInner(VolumeInfo vol)23930     private void loadPrivatePackagesInner(VolumeInfo vol) {
23931         final String volumeUuid = vol.fsUuid;
23932         if (TextUtils.isEmpty(volumeUuid)) {
23933             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
23934             return;
23935         }
23936 
23937         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
23938         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
23939         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
23940 
23941         final VersionInfo ver;
23942         final List<PackageSetting> packages;
23943         synchronized (mPackages) {
23944             ver = mSettings.findOrCreateVersion(volumeUuid);
23945             packages = mSettings.getVolumePackagesLPr(volumeUuid);
23946         }
23947 
23948         for (PackageSetting ps : packages) {
23949             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
23950             synchronized (mInstallLock) {
23951                 final PackageParser.Package pkg;
23952                 try {
23953                     pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
23954                     loaded.add(pkg.applicationInfo);
23955 
23956                 } catch (PackageManagerException e) {
23957                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
23958                 }
23959 
23960                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
23961                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
23962                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
23963                                     | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
23964                 }
23965             }
23966         }
23967 
23968         // Reconcile app data for all started/unlocked users
23969         final StorageManager sm = mContext.getSystemService(StorageManager.class);
23970         final UserManager um = mContext.getSystemService(UserManager.class);
23971         UserManagerInternal umInternal = getUserManagerInternal();
23972         for (UserInfo user : um.getUsers()) {
23973             final int flags;
23974             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23975                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23976             } else if (umInternal.isUserRunning(user.id)) {
23977                 flags = StorageManager.FLAG_STORAGE_DE;
23978             } else {
23979                 continue;
23980             }
23981 
23982             try {
23983                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
23984                 synchronized (mInstallLock) {
23985                     reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
23986                 }
23987             } catch (IllegalStateException e) {
23988                 // Device was probably ejected, and we'll process that event momentarily
23989                 Slog.w(TAG, "Failed to prepare storage: " + e);
23990             }
23991         }
23992 
23993         synchronized (mPackages) {
23994             int updateFlags = UPDATE_PERMISSIONS_ALL;
23995             if (ver.sdkVersion != mSdkVersion) {
23996                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23997                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
23998                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23999             }
24000             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
24001 
24002             // Yay, everything is now upgraded
24003             ver.forceCurrent();
24004 
24005             mSettings.writeLPr();
24006         }
24007 
24008         for (PackageFreezer freezer : freezers) {
24009             freezer.close();
24010         }
24011 
24012         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
24013         sendResourcesChangedBroadcast(true, false, loaded, null);
24014         mLoadedVolumes.add(vol.getId());
24015     }
24016 
unloadPrivatePackages(final VolumeInfo vol)24017     private void unloadPrivatePackages(final VolumeInfo vol) {
24018         mHandler.post(new Runnable() {
24019             @Override
24020             public void run() {
24021                 unloadPrivatePackagesInner(vol);
24022             }
24023         });
24024     }
24025 
unloadPrivatePackagesInner(VolumeInfo vol)24026     private void unloadPrivatePackagesInner(VolumeInfo vol) {
24027         final String volumeUuid = vol.fsUuid;
24028         if (TextUtils.isEmpty(volumeUuid)) {
24029             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
24030             return;
24031         }
24032 
24033         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
24034         synchronized (mInstallLock) {
24035         synchronized (mPackages) {
24036             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
24037             for (PackageSetting ps : packages) {
24038                 if (ps.pkg == null) continue;
24039 
24040                 final ApplicationInfo info = ps.pkg.applicationInfo;
24041                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
24042                 final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
24043 
24044                 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
24045                         "unloadPrivatePackagesInner")) {
24046                     if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
24047                             false, null)) {
24048                         unloaded.add(info);
24049                     } else {
24050                         Slog.w(TAG, "Failed to unload " + ps.codePath);
24051                     }
24052                 }
24053 
24054                 // Try very hard to release any references to this package
24055                 // so we don't risk the system server being killed due to
24056                 // open FDs
24057                 AttributeCache.instance().removePackage(ps.name);
24058             }
24059 
24060             mSettings.writeLPr();
24061         }
24062         }
24063 
24064         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
24065         sendResourcesChangedBroadcast(false, false, unloaded, null);
24066         mLoadedVolumes.remove(vol.getId());
24067 
24068         // Try very hard to release any references to this path so we don't risk
24069         // the system server being killed due to open FDs
24070         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
24071 
24072         for (int i = 0; i < 3; i++) {
24073             System.gc();
24074             System.runFinalization();
24075         }
24076     }
24077 
assertPackageKnown(String volumeUuid, String packageName)24078     private void assertPackageKnown(String volumeUuid, String packageName)
24079             throws PackageManagerException {
24080         synchronized (mPackages) {
24081             // Normalize package name to handle renamed packages
24082             packageName = normalizePackageNameLPr(packageName);
24083 
24084             final PackageSetting ps = mSettings.mPackages.get(packageName);
24085             if (ps == null) {
24086                 throw new PackageManagerException("Package " + packageName + " is unknown");
24087             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
24088                 throw new PackageManagerException(
24089                         "Package " + packageName + " found on unknown volume " + volumeUuid
24090                                 + "; expected volume " + ps.volumeUuid);
24091             }
24092         }
24093     }
24094 
assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)24095     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
24096             throws PackageManagerException {
24097         synchronized (mPackages) {
24098             // Normalize package name to handle renamed packages
24099             packageName = normalizePackageNameLPr(packageName);
24100 
24101             final PackageSetting ps = mSettings.mPackages.get(packageName);
24102             if (ps == null) {
24103                 throw new PackageManagerException("Package " + packageName + " is unknown");
24104             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
24105                 throw new PackageManagerException(
24106                         "Package " + packageName + " found on unknown volume " + volumeUuid
24107                                 + "; expected volume " + ps.volumeUuid);
24108             } else if (!ps.getInstalled(userId)) {
24109                 throw new PackageManagerException(
24110                         "Package " + packageName + " not installed for user " + userId);
24111             }
24112         }
24113     }
24114 
collectAbsoluteCodePaths()24115     private List<String> collectAbsoluteCodePaths() {
24116         synchronized (mPackages) {
24117             List<String> codePaths = new ArrayList<>();
24118             final int packageCount = mSettings.mPackages.size();
24119             for (int i = 0; i < packageCount; i++) {
24120                 final PackageSetting ps = mSettings.mPackages.valueAt(i);
24121                 codePaths.add(ps.codePath.getAbsolutePath());
24122             }
24123             return codePaths;
24124         }
24125     }
24126 
24127     /**
24128      * Examine all apps present on given mounted volume, and destroy apps that
24129      * aren't expected, either due to uninstallation or reinstallation on
24130      * another volume.
24131      */
reconcileApps(String volumeUuid)24132     private void reconcileApps(String volumeUuid) {
24133         List<String> absoluteCodePaths = collectAbsoluteCodePaths();
24134         List<File> filesToDelete = null;
24135 
24136         final File[] files = FileUtils.listFilesOrEmpty(
24137                 Environment.getDataAppDirectory(volumeUuid));
24138         for (File file : files) {
24139             final boolean isPackage = (isApkFile(file) || file.isDirectory())
24140                     && !PackageInstallerService.isStageName(file.getName());
24141             if (!isPackage) {
24142                 // Ignore entries which are not packages
24143                 continue;
24144             }
24145 
24146             String absolutePath = file.getAbsolutePath();
24147 
24148             boolean pathValid = false;
24149             final int absoluteCodePathCount = absoluteCodePaths.size();
24150             for (int i = 0; i < absoluteCodePathCount; i++) {
24151                 String absoluteCodePath = absoluteCodePaths.get(i);
24152                 if (absolutePath.startsWith(absoluteCodePath)) {
24153                     pathValid = true;
24154                     break;
24155                 }
24156             }
24157 
24158             if (!pathValid) {
24159                 if (filesToDelete == null) {
24160                     filesToDelete = new ArrayList<>();
24161                 }
24162                 filesToDelete.add(file);
24163             }
24164         }
24165 
24166         if (filesToDelete != null) {
24167             final int fileToDeleteCount = filesToDelete.size();
24168             for (int i = 0; i < fileToDeleteCount; i++) {
24169                 File fileToDelete = filesToDelete.get(i);
24170                 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
24171                 synchronized (mInstallLock) {
24172                     removeCodePathLI(fileToDelete);
24173                 }
24174             }
24175         }
24176     }
24177 
24178     /**
24179      * Reconcile all app data for the given user.
24180      * <p>
24181      * Verifies that directories exist and that ownership and labeling is
24182      * correct for all installed apps on all mounted volumes.
24183      */
reconcileAppsData(int userId, int flags, boolean migrateAppsData)24184     void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
24185         final StorageManager storage = mContext.getSystemService(StorageManager.class);
24186         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
24187             final String volumeUuid = vol.getFsUuid();
24188             synchronized (mInstallLock) {
24189                 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
24190             }
24191         }
24192     }
24193 
reconcileAppsDataLI(String volumeUuid, int userId, int flags, boolean migrateAppData)24194     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
24195             boolean migrateAppData) {
24196         reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
24197     }
24198 
24199     /**
24200      * Reconcile all app data on given mounted volume.
24201      * <p>
24202      * Destroys app data that isn't expected, either due to uninstallation or
24203      * reinstallation on another volume.
24204      * <p>
24205      * Verifies that directories exist and that ownership and labeling is
24206      * correct for all installed apps.
24207      * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
24208      */
reconcileAppsDataLI(String volumeUuid, int userId, int flags, boolean migrateAppData, boolean onlyCoreApps)24209     private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
24210             boolean migrateAppData, boolean onlyCoreApps) {
24211         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
24212                 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
24213         List<String> result = onlyCoreApps ? new ArrayList<>() : null;
24214 
24215         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
24216         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
24217 
24218         // First look for stale data that doesn't belong, and check if things
24219         // have changed since we did our last restorecon
24220         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
24221             if (StorageManager.isFileEncryptedNativeOrEmulated()
24222                     && !StorageManager.isUserKeyUnlocked(userId)) {
24223                 throw new RuntimeException(
24224                         "Yikes, someone asked us to reconcile CE storage while " + userId
24225                                 + " was still locked; this would have caused massive data loss!");
24226             }
24227 
24228             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
24229             for (File file : files) {
24230                 final String packageName = file.getName();
24231                 try {
24232                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
24233                 } catch (PackageManagerException e) {
24234                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
24235                     try {
24236                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
24237                                 StorageManager.FLAG_STORAGE_CE, 0);
24238                     } catch (InstallerException e2) {
24239                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
24240                     }
24241                 }
24242             }
24243         }
24244         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
24245             final File[] files = FileUtils.listFilesOrEmpty(deDir);
24246             for (File file : files) {
24247                 final String packageName = file.getName();
24248                 try {
24249                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
24250                 } catch (PackageManagerException e) {
24251                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
24252                     try {
24253                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
24254                                 StorageManager.FLAG_STORAGE_DE, 0);
24255                     } catch (InstallerException e2) {
24256                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
24257                     }
24258                 }
24259             }
24260         }
24261 
24262         // Ensure that data directories are ready to roll for all packages
24263         // installed for this volume and user
24264         final List<PackageSetting> packages;
24265         synchronized (mPackages) {
24266             packages = mSettings.getVolumePackagesLPr(volumeUuid);
24267         }
24268         int preparedCount = 0;
24269         for (PackageSetting ps : packages) {
24270             final String packageName = ps.name;
24271             if (ps.pkg == null) {
24272                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
24273                 // TODO: might be due to legacy ASEC apps; we should circle back
24274                 // and reconcile again once they're scanned
24275                 continue;
24276             }
24277             // Skip non-core apps if requested
24278             if (onlyCoreApps && !ps.pkg.coreApp) {
24279                 result.add(packageName);
24280                 continue;
24281             }
24282 
24283             if (ps.getInstalled(userId)) {
24284                 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
24285                 preparedCount++;
24286             }
24287         }
24288 
24289         Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
24290         return result;
24291     }
24292 
24293     /**
24294      * Prepare app data for the given app just after it was installed or
24295      * upgraded. This method carefully only touches users that it's installed
24296      * for, and it forces a restorecon to handle any seinfo changes.
24297      * <p>
24298      * Verifies that directories exist and that ownership and labeling is
24299      * correct for all installed apps. If there is an ownership mismatch, it
24300      * will try recovering system apps by wiping data; third-party app data is
24301      * left intact.
24302      * <p>
24303      * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
24304      */
prepareAppDataAfterInstallLIF(PackageParser.Package pkg)24305     private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
24306         final PackageSetting ps;
24307         synchronized (mPackages) {
24308             ps = mSettings.mPackages.get(pkg.packageName);
24309             mSettings.writeKernelMappingLPr(ps);
24310         }
24311 
24312         final UserManagerService um = sUserManager;
24313         UserManagerInternal umInternal = getUserManagerInternal();
24314         for (UserInfo user : um.getUsers(false /* excludeDying */)) {
24315             final int flags;
24316             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
24317                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
24318             } else if (umInternal.isUserRunning(user.id)) {
24319                 flags = StorageManager.FLAG_STORAGE_DE;
24320             } else {
24321                 continue;
24322             }
24323 
24324             if (ps.getInstalled(user.id)) {
24325                 // TODO: when user data is locked, mark that we're still dirty
24326                 prepareAppDataLIF(pkg, user.id, flags);
24327             }
24328         }
24329     }
24330 
24331     /**
24332      * Prepare app data for the given app.
24333      * <p>
24334      * Verifies that directories exist and that ownership and labeling is
24335      * correct for all installed apps. If there is an ownership mismatch, this
24336      * will try recovering system apps by wiping data; third-party app data is
24337      * left intact.
24338      */
prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags)24339     private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
24340         if (pkg == null) {
24341             Slog.wtf(TAG, "Package was null!", new Throwable());
24342             return;
24343         }
24344         prepareAppDataLeafLIF(pkg, userId, flags);
24345         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24346         for (int i = 0; i < childCount; i++) {
24347             prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
24348         }
24349     }
24350 
prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags, boolean maybeMigrateAppData)24351     private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
24352             boolean maybeMigrateAppData) {
24353         prepareAppDataLIF(pkg, userId, flags);
24354 
24355         if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
24356             // We may have just shuffled around app data directories, so
24357             // prepare them one more time
24358             prepareAppDataLIF(pkg, userId, flags);
24359         }
24360     }
24361 
prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags)24362     private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24363         if (DEBUG_APP_DATA) {
24364             Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
24365                     + Integer.toHexString(flags));
24366         }
24367 
24368         final String volumeUuid = pkg.volumeUuid;
24369         final String packageName = pkg.packageName;
24370         final ApplicationInfo app = pkg.applicationInfo;
24371         final int appId = UserHandle.getAppId(app.uid);
24372 
24373         Preconditions.checkNotNull(app.seInfo);
24374 
24375         long ceDataInode = -1;
24376         try {
24377             ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24378                     appId, app.seInfo, app.targetSdkVersion);
24379         } catch (InstallerException e) {
24380             if (app.isSystemApp()) {
24381                 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
24382                         + ", but trying to recover: " + e);
24383                 destroyAppDataLeafLIF(pkg, userId, flags);
24384                 try {
24385                     ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24386                             appId, app.seInfo, app.targetSdkVersion);
24387                     logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
24388                 } catch (InstallerException e2) {
24389                     logCriticalInfo(Log.DEBUG, "Recovery failed!");
24390                 }
24391             } else {
24392                 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
24393             }
24394         }
24395 
24396         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
24397             // TODO: mark this structure as dirty so we persist it!
24398             synchronized (mPackages) {
24399                 final PackageSetting ps = mSettings.mPackages.get(packageName);
24400                 if (ps != null) {
24401                     ps.setCeDataInode(ceDataInode, userId);
24402                 }
24403             }
24404         }
24405 
24406         prepareAppDataContentsLeafLIF(pkg, userId, flags);
24407     }
24408 
prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags)24409     private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
24410         if (pkg == null) {
24411             Slog.wtf(TAG, "Package was null!", new Throwable());
24412             return;
24413         }
24414         prepareAppDataContentsLeafLIF(pkg, userId, flags);
24415         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24416         for (int i = 0; i < childCount; i++) {
24417             prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
24418         }
24419     }
24420 
prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags)24421     private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24422         final String volumeUuid = pkg.volumeUuid;
24423         final String packageName = pkg.packageName;
24424         final ApplicationInfo app = pkg.applicationInfo;
24425 
24426         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
24427             // Create a native library symlink only if we have native libraries
24428             // and if the native libraries are 32 bit libraries. We do not provide
24429             // this symlink for 64 bit libraries.
24430             if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
24431                 final String nativeLibPath = app.nativeLibraryDir;
24432                 try {
24433                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
24434                             nativeLibPath, userId);
24435                 } catch (InstallerException e) {
24436                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
24437                 }
24438             }
24439         }
24440     }
24441 
24442     /**
24443      * For system apps on non-FBE devices, this method migrates any existing
24444      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
24445      * requested by the app.
24446      */
maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId)24447     private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
24448         if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
24449                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
24450             final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
24451                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
24452             try {
24453                 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
24454                         storageTarget);
24455             } catch (InstallerException e) {
24456                 logCriticalInfo(Log.WARN,
24457                         "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
24458             }
24459             return true;
24460         } else {
24461             return false;
24462         }
24463     }
24464 
freezePackage(String packageName, String killReason)24465     public PackageFreezer freezePackage(String packageName, String killReason) {
24466         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
24467     }
24468 
freezePackage(String packageName, int userId, String killReason)24469     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
24470         return new PackageFreezer(packageName, userId, killReason);
24471     }
24472 
freezePackageForInstall(String packageName, int installFlags, String killReason)24473     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
24474             String killReason) {
24475         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
24476     }
24477 
freezePackageForInstall(String packageName, int userId, int installFlags, String killReason)24478     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
24479             String killReason) {
24480         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
24481             return new PackageFreezer();
24482         } else {
24483             return freezePackage(packageName, userId, killReason);
24484         }
24485     }
24486 
freezePackageForDelete(String packageName, int deleteFlags, String killReason)24487     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
24488             String killReason) {
24489         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
24490     }
24491 
freezePackageForDelete(String packageName, int userId, int deleteFlags, String killReason)24492     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
24493             String killReason) {
24494         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
24495             return new PackageFreezer();
24496         } else {
24497             return freezePackage(packageName, userId, killReason);
24498         }
24499     }
24500 
24501     /**
24502      * Class that freezes and kills the given package upon creation, and
24503      * unfreezes it upon closing. This is typically used when doing surgery on
24504      * app code/data to prevent the app from running while you're working.
24505      */
24506     private class PackageFreezer implements AutoCloseable {
24507         private final String mPackageName;
24508         private final PackageFreezer[] mChildren;
24509 
24510         private final boolean mWeFroze;
24511 
24512         private final AtomicBoolean mClosed = new AtomicBoolean();
24513         private final CloseGuard mCloseGuard = CloseGuard.get();
24514 
24515         /**
24516          * Create and return a stub freezer that doesn't actually do anything,
24517          * typically used when someone requested
24518          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
24519          * {@link PackageManager#DELETE_DONT_KILL_APP}.
24520          */
PackageFreezer()24521         public PackageFreezer() {
24522             mPackageName = null;
24523             mChildren = null;
24524             mWeFroze = false;
24525             mCloseGuard.open("close");
24526         }
24527 
PackageFreezer(String packageName, int userId, String killReason)24528         public PackageFreezer(String packageName, int userId, String killReason) {
24529             synchronized (mPackages) {
24530                 mPackageName = packageName;
24531                 mWeFroze = mFrozenPackages.add(mPackageName);
24532 
24533                 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
24534                 if (ps != null) {
24535                     killApplication(ps.name, ps.appId, userId, killReason);
24536                 }
24537 
24538                 final PackageParser.Package p = mPackages.get(packageName);
24539                 if (p != null && p.childPackages != null) {
24540                     final int N = p.childPackages.size();
24541                     mChildren = new PackageFreezer[N];
24542                     for (int i = 0; i < N; i++) {
24543                         mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
24544                                 userId, killReason);
24545                     }
24546                 } else {
24547                     mChildren = null;
24548                 }
24549             }
24550             mCloseGuard.open("close");
24551         }
24552 
24553         @Override
finalize()24554         protected void finalize() throws Throwable {
24555             try {
24556                 if (mCloseGuard != null) {
24557                     mCloseGuard.warnIfOpen();
24558                 }
24559 
24560                 close();
24561             } finally {
24562                 super.finalize();
24563             }
24564         }
24565 
24566         @Override
close()24567         public void close() {
24568             mCloseGuard.close();
24569             if (mClosed.compareAndSet(false, true)) {
24570                 synchronized (mPackages) {
24571                     if (mWeFroze) {
24572                         mFrozenPackages.remove(mPackageName);
24573                     }
24574 
24575                     if (mChildren != null) {
24576                         for (PackageFreezer freezer : mChildren) {
24577                             freezer.close();
24578                         }
24579                     }
24580                 }
24581             }
24582         }
24583     }
24584 
24585     /**
24586      * Verify that given package is currently frozen.
24587      */
checkPackageFrozen(String packageName)24588     private void checkPackageFrozen(String packageName) {
24589         synchronized (mPackages) {
24590             if (!mFrozenPackages.contains(packageName)) {
24591                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
24592             }
24593         }
24594     }
24595 
24596     @Override
movePackage(final String packageName, final String volumeUuid)24597     public int movePackage(final String packageName, final String volumeUuid) {
24598         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24599 
24600         final int callingUid = Binder.getCallingUid();
24601         final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
24602         final int moveId = mNextMoveId.getAndIncrement();
24603         mHandler.post(new Runnable() {
24604             @Override
24605             public void run() {
24606                 try {
24607                     movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
24608                 } catch (PackageManagerException e) {
24609                     Slog.w(TAG, "Failed to move " + packageName, e);
24610                     mMoveCallbacks.notifyStatusChanged(moveId, e.error);
24611                 }
24612             }
24613         });
24614         return moveId;
24615     }
24616 
movePackageInternal(final String packageName, final String volumeUuid, final int moveId, final int callingUid, UserHandle user)24617     private void movePackageInternal(final String packageName, final String volumeUuid,
24618             final int moveId, final int callingUid, UserHandle user)
24619                     throws PackageManagerException {
24620         final StorageManager storage = mContext.getSystemService(StorageManager.class);
24621         final PackageManager pm = mContext.getPackageManager();
24622 
24623         final boolean currentAsec;
24624         final String currentVolumeUuid;
24625         final File codeFile;
24626         final String installerPackageName;
24627         final String packageAbiOverride;
24628         final int appId;
24629         final String seinfo;
24630         final String label;
24631         final int targetSdkVersion;
24632         final PackageFreezer freezer;
24633         final int[] installedUserIds;
24634 
24635         // reader
24636         synchronized (mPackages) {
24637             final PackageParser.Package pkg = mPackages.get(packageName);
24638             final PackageSetting ps = mSettings.mPackages.get(packageName);
24639             if (pkg == null
24640                     || ps == null
24641                     || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
24642                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
24643             }
24644             if (pkg.applicationInfo.isSystemApp()) {
24645                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
24646                         "Cannot move system application");
24647             }
24648 
24649             final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
24650             final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
24651                     com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
24652             if (isInternalStorage && !allow3rdPartyOnInternal) {
24653                 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
24654                         "3rd party apps are not allowed on internal storage");
24655             }
24656 
24657             if (pkg.applicationInfo.isExternalAsec()) {
24658                 currentAsec = true;
24659                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
24660             } else if (pkg.applicationInfo.isForwardLocked()) {
24661                 currentAsec = true;
24662                 currentVolumeUuid = "forward_locked";
24663             } else {
24664                 currentAsec = false;
24665                 currentVolumeUuid = ps.volumeUuid;
24666 
24667                 final File probe = new File(pkg.codePath);
24668                 final File probeOat = new File(probe, "oat");
24669                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
24670                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24671                             "Move only supported for modern cluster style installs");
24672                 }
24673             }
24674 
24675             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
24676                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24677                         "Package already moved to " + volumeUuid);
24678             }
24679             if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
24680                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
24681                         "Device admin cannot be moved");
24682             }
24683 
24684             if (mFrozenPackages.contains(packageName)) {
24685                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
24686                         "Failed to move already frozen package");
24687             }
24688 
24689             codeFile = new File(pkg.codePath);
24690             installerPackageName = ps.installerPackageName;
24691             packageAbiOverride = ps.cpuAbiOverrideString;
24692             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
24693             seinfo = pkg.applicationInfo.seInfo;
24694             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
24695             targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
24696             freezer = freezePackage(packageName, "movePackageInternal");
24697             installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
24698         }
24699 
24700         final Bundle extras = new Bundle();
24701         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
24702         extras.putString(Intent.EXTRA_TITLE, label);
24703         mMoveCallbacks.notifyCreated(moveId, extras);
24704 
24705         int installFlags;
24706         final boolean moveCompleteApp;
24707         final File measurePath;
24708 
24709         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
24710             installFlags = INSTALL_INTERNAL;
24711             moveCompleteApp = !currentAsec;
24712             measurePath = Environment.getDataAppDirectory(volumeUuid);
24713         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
24714             installFlags = INSTALL_EXTERNAL;
24715             moveCompleteApp = false;
24716             measurePath = storage.getPrimaryPhysicalVolume().getPath();
24717         } else {
24718             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
24719             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
24720                     || !volume.isMountedWritable()) {
24721                 freezer.close();
24722                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24723                         "Move location not mounted private volume");
24724             }
24725 
24726             Preconditions.checkState(!currentAsec);
24727 
24728             installFlags = INSTALL_INTERNAL;
24729             moveCompleteApp = true;
24730             measurePath = Environment.getDataAppDirectory(volumeUuid);
24731         }
24732 
24733         // If we're moving app data around, we need all the users unlocked
24734         if (moveCompleteApp) {
24735             for (int userId : installedUserIds) {
24736                 if (StorageManager.isFileEncryptedNativeOrEmulated()
24737                         && !StorageManager.isUserKeyUnlocked(userId)) {
24738                     throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
24739                             "User " + userId + " must be unlocked");
24740                 }
24741             }
24742         }
24743 
24744         final PackageStats stats = new PackageStats(null, -1);
24745         synchronized (mInstaller) {
24746             for (int userId : installedUserIds) {
24747                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
24748                     freezer.close();
24749                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24750                             "Failed to measure package size");
24751                 }
24752             }
24753         }
24754 
24755         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
24756                 + stats.dataSize);
24757 
24758         final long startFreeBytes = measurePath.getUsableSpace();
24759         final long sizeBytes;
24760         if (moveCompleteApp) {
24761             sizeBytes = stats.codeSize + stats.dataSize;
24762         } else {
24763             sizeBytes = stats.codeSize;
24764         }
24765 
24766         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
24767             freezer.close();
24768             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24769                     "Not enough free space to move");
24770         }
24771 
24772         mMoveCallbacks.notifyStatusChanged(moveId, 10);
24773 
24774         final CountDownLatch installedLatch = new CountDownLatch(1);
24775         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
24776             @Override
24777             public void onUserActionRequired(Intent intent) throws RemoteException {
24778                 throw new IllegalStateException();
24779             }
24780 
24781             @Override
24782             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
24783                     Bundle extras) throws RemoteException {
24784                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
24785                         + PackageManager.installStatusToString(returnCode, msg));
24786 
24787                 installedLatch.countDown();
24788                 freezer.close();
24789 
24790                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
24791                 switch (status) {
24792                     case PackageInstaller.STATUS_SUCCESS:
24793                         mMoveCallbacks.notifyStatusChanged(moveId,
24794                                 PackageManager.MOVE_SUCCEEDED);
24795                         break;
24796                     case PackageInstaller.STATUS_FAILURE_STORAGE:
24797                         mMoveCallbacks.notifyStatusChanged(moveId,
24798                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
24799                         break;
24800                     default:
24801                         mMoveCallbacks.notifyStatusChanged(moveId,
24802                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
24803                         break;
24804                 }
24805             }
24806         };
24807 
24808         final MoveInfo move;
24809         if (moveCompleteApp) {
24810             // Kick off a thread to report progress estimates
24811             new Thread() {
24812                 @Override
24813                 public void run() {
24814                     while (true) {
24815                         try {
24816                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
24817                                 break;
24818                             }
24819                         } catch (InterruptedException ignored) {
24820                         }
24821 
24822                         final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
24823                         final int progress = 10 + (int) MathUtils.constrain(
24824                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
24825                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
24826                     }
24827                 }
24828             }.start();
24829 
24830             final String dataAppName = codeFile.getName();
24831             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
24832                     dataAppName, appId, seinfo, targetSdkVersion);
24833         } else {
24834             move = null;
24835         }
24836 
24837         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
24838 
24839         final Message msg = mHandler.obtainMessage(INIT_COPY);
24840         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
24841         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
24842                 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
24843                 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
24844                 PackageManager.INSTALL_REASON_UNKNOWN);
24845         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
24846         msg.obj = params;
24847 
24848         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
24849                 System.identityHashCode(msg.obj));
24850         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
24851                 System.identityHashCode(msg.obj));
24852 
24853         mHandler.sendMessage(msg);
24854     }
24855 
24856     @Override
movePrimaryStorage(String volumeUuid)24857     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
24858         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24859 
24860         final int realMoveId = mNextMoveId.getAndIncrement();
24861         final Bundle extras = new Bundle();
24862         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
24863         mMoveCallbacks.notifyCreated(realMoveId, extras);
24864 
24865         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
24866             @Override
24867             public void onCreated(int moveId, Bundle extras) {
24868                 // Ignored
24869             }
24870 
24871             @Override
24872             public void onStatusChanged(int moveId, int status, long estMillis) {
24873                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
24874             }
24875         };
24876 
24877         final StorageManager storage = mContext.getSystemService(StorageManager.class);
24878         storage.setPrimaryStorageUuid(volumeUuid, callback);
24879         return realMoveId;
24880     }
24881 
24882     @Override
getMoveStatus(int moveId)24883     public int getMoveStatus(int moveId) {
24884         mContext.enforceCallingOrSelfPermission(
24885                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24886         return mMoveCallbacks.mLastStatus.get(moveId);
24887     }
24888 
24889     @Override
registerMoveCallback(IPackageMoveObserver callback)24890     public void registerMoveCallback(IPackageMoveObserver callback) {
24891         mContext.enforceCallingOrSelfPermission(
24892                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24893         mMoveCallbacks.register(callback);
24894     }
24895 
24896     @Override
unregisterMoveCallback(IPackageMoveObserver callback)24897     public void unregisterMoveCallback(IPackageMoveObserver callback) {
24898         mContext.enforceCallingOrSelfPermission(
24899                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24900         mMoveCallbacks.unregister(callback);
24901     }
24902 
24903     @Override
setInstallLocation(int loc)24904     public boolean setInstallLocation(int loc) {
24905         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
24906                 null);
24907         if (getInstallLocation() == loc) {
24908             return true;
24909         }
24910         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
24911                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
24912             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
24913                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
24914             return true;
24915         }
24916         return false;
24917    }
24918 
24919     @Override
getInstallLocation()24920     public int getInstallLocation() {
24921         // allow instant app access
24922         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
24923                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
24924                 PackageHelper.APP_INSTALL_AUTO);
24925     }
24926 
24927     /** Called by UserManagerService */
cleanUpUser(UserManagerService userManager, int userHandle)24928     void cleanUpUser(UserManagerService userManager, int userHandle) {
24929         synchronized (mPackages) {
24930             mDirtyUsers.remove(userHandle);
24931             mUserNeedsBadging.delete(userHandle);
24932             mSettings.removeUserLPw(userHandle);
24933             mPendingBroadcasts.remove(userHandle);
24934             mInstantAppRegistry.onUserRemovedLPw(userHandle);
24935             removeUnusedPackagesLPw(userManager, userHandle);
24936         }
24937     }
24938 
24939     /**
24940      * We're removing userHandle and would like to remove any downloaded packages
24941      * that are no longer in use by any other user.
24942      * @param userHandle the user being removed
24943      */
removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle)24944     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
24945         final boolean DEBUG_CLEAN_APKS = false;
24946         int [] users = userManager.getUserIds();
24947         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
24948         while (psit.hasNext()) {
24949             PackageSetting ps = psit.next();
24950             if (ps.pkg == null) {
24951                 continue;
24952             }
24953             final String packageName = ps.pkg.packageName;
24954             // Skip over if system app or static shared library
24955             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
24956                     || !TextUtils.isEmpty(ps.pkg.staticSharedLibName)) {
24957                 continue;
24958             }
24959             if (DEBUG_CLEAN_APKS) {
24960                 Slog.i(TAG, "Checking package " + packageName);
24961             }
24962             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
24963             if (keep) {
24964                 if (DEBUG_CLEAN_APKS) {
24965                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
24966                 }
24967             } else {
24968                 for (int i = 0; i < users.length; i++) {
24969                     if (users[i] != userHandle && ps.getInstalled(users[i])) {
24970                         keep = true;
24971                         if (DEBUG_CLEAN_APKS) {
24972                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
24973                                     + users[i]);
24974                         }
24975                         break;
24976                     }
24977                 }
24978             }
24979             if (!keep) {
24980                 if (DEBUG_CLEAN_APKS) {
24981                     Slog.i(TAG, "  Removing package " + packageName);
24982                 }
24983                 mHandler.post(new Runnable() {
24984                     public void run() {
24985                         deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24986                                 userHandle, 0);
24987                     } //end run
24988                 });
24989             }
24990         }
24991     }
24992 
24993     /** Called by UserManagerService */
createNewUser(int userId, String[] disallowedPackages)24994     void createNewUser(int userId, String[] disallowedPackages) {
24995         synchronized (mInstallLock) {
24996             mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
24997         }
24998         synchronized (mPackages) {
24999             scheduleWritePackageRestrictionsLocked(userId);
25000             scheduleWritePackageListLocked(userId);
25001             applyFactoryDefaultBrowserLPw(userId);
25002             primeDomainVerificationsLPw(userId);
25003         }
25004     }
25005 
onNewUserCreated(final int userId)25006     void onNewUserCreated(final int userId) {
25007         mDefaultPermissionPolicy.grantDefaultPermissions(userId);
25008         // If permission review for legacy apps is required, we represent
25009         // dagerous permissions for such apps as always granted runtime
25010         // permissions to keep per user flag state whether review is needed.
25011         // Hence, if a new user is added we have to propagate dangerous
25012         // permission grants for these legacy apps.
25013         if (mPermissionReviewRequired) {
25014             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
25015                     | UPDATE_PERMISSIONS_REPLACE_ALL);
25016         }
25017     }
25018 
25019     @Override
getVerifierDeviceIdentity()25020     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
25021         mContext.enforceCallingOrSelfPermission(
25022                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
25023                 "Only package verification agents can read the verifier device identity");
25024 
25025         synchronized (mPackages) {
25026             return mSettings.getVerifierDeviceIdentityLPw();
25027         }
25028     }
25029 
25030     @Override
setPermissionEnforced(String permission, boolean enforced)25031     public void setPermissionEnforced(String permission, boolean enforced) {
25032         // TODO: Now that we no longer change GID for storage, this should to away.
25033         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
25034                 "setPermissionEnforced");
25035         if (READ_EXTERNAL_STORAGE.equals(permission)) {
25036             synchronized (mPackages) {
25037                 if (mSettings.mReadExternalStorageEnforced == null
25038                         || mSettings.mReadExternalStorageEnforced != enforced) {
25039                     mSettings.mReadExternalStorageEnforced = enforced;
25040                     mSettings.writeLPr();
25041                 }
25042             }
25043             // kill any non-foreground processes so we restart them and
25044             // grant/revoke the GID.
25045             final IActivityManager am = ActivityManager.getService();
25046             if (am != null) {
25047                 final long token = Binder.clearCallingIdentity();
25048                 try {
25049                     am.killProcessesBelowForeground("setPermissionEnforcement");
25050                 } catch (RemoteException e) {
25051                 } finally {
25052                     Binder.restoreCallingIdentity(token);
25053                 }
25054             }
25055         } else {
25056             throw new IllegalArgumentException("No selective enforcement for " + permission);
25057         }
25058     }
25059 
25060     @Override
25061     @Deprecated
isPermissionEnforced(String permission)25062     public boolean isPermissionEnforced(String permission) {
25063         // allow instant applications
25064         return true;
25065     }
25066 
25067     @Override
isStorageLow()25068     public boolean isStorageLow() {
25069         // allow instant applications
25070         final long token = Binder.clearCallingIdentity();
25071         try {
25072             final DeviceStorageMonitorInternal
25073                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
25074             if (dsm != null) {
25075                 return dsm.isMemoryLow();
25076             } else {
25077                 return false;
25078             }
25079         } finally {
25080             Binder.restoreCallingIdentity(token);
25081         }
25082     }
25083 
25084     @Override
getPackageInstaller()25085     public IPackageInstaller getPackageInstaller() {
25086         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25087             return null;
25088         }
25089         return mInstallerService;
25090     }
25091 
userNeedsBadging(int userId)25092     private boolean userNeedsBadging(int userId) {
25093         int index = mUserNeedsBadging.indexOfKey(userId);
25094         if (index < 0) {
25095             final UserInfo userInfo;
25096             final long token = Binder.clearCallingIdentity();
25097             try {
25098                 userInfo = sUserManager.getUserInfo(userId);
25099             } finally {
25100                 Binder.restoreCallingIdentity(token);
25101             }
25102             final boolean b;
25103             if (userInfo != null && userInfo.isManagedProfile()) {
25104                 b = true;
25105             } else {
25106                 b = false;
25107             }
25108             mUserNeedsBadging.put(userId, b);
25109             return b;
25110         }
25111         return mUserNeedsBadging.valueAt(index);
25112     }
25113 
25114     @Override
getKeySetByAlias(String packageName, String alias)25115     public KeySet getKeySetByAlias(String packageName, String alias) {
25116         if (packageName == null || alias == null) {
25117             return null;
25118         }
25119         synchronized(mPackages) {
25120             final PackageParser.Package pkg = mPackages.get(packageName);
25121             if (pkg == null) {
25122                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25123                 throw new IllegalArgumentException("Unknown package: " + packageName);
25124             }
25125             final PackageSetting ps = (PackageSetting) pkg.mExtras;
25126             if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
25127                 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
25128                 throw new IllegalArgumentException("Unknown package: " + packageName);
25129             }
25130             KeySetManagerService ksms = mSettings.mKeySetManagerService;
25131             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
25132         }
25133     }
25134 
25135     @Override
getSigningKeySet(String packageName)25136     public KeySet getSigningKeySet(String packageName) {
25137         if (packageName == null) {
25138             return null;
25139         }
25140         synchronized(mPackages) {
25141             final int callingUid = Binder.getCallingUid();
25142             final int callingUserId = UserHandle.getUserId(callingUid);
25143             final PackageParser.Package pkg = mPackages.get(packageName);
25144             if (pkg == null) {
25145                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25146                 throw new IllegalArgumentException("Unknown package: " + packageName);
25147             }
25148             final PackageSetting ps = (PackageSetting) pkg.mExtras;
25149             if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
25150                 // filter and pretend the package doesn't exist
25151                 Slog.w(TAG, "KeySet requested for filtered package: " + packageName
25152                         + ", uid:" + callingUid);
25153                 throw new IllegalArgumentException("Unknown package: " + packageName);
25154             }
25155             if (pkg.applicationInfo.uid != callingUid
25156                     && Process.SYSTEM_UID != callingUid) {
25157                 throw new SecurityException("May not access signing KeySet of other apps.");
25158             }
25159             KeySetManagerService ksms = mSettings.mKeySetManagerService;
25160             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
25161         }
25162     }
25163 
25164     @Override
isPackageSignedByKeySet(String packageName, KeySet ks)25165     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
25166         final int callingUid = Binder.getCallingUid();
25167         if (getInstantAppPackageName(callingUid) != null) {
25168             return false;
25169         }
25170         if (packageName == null || ks == null) {
25171             return false;
25172         }
25173         synchronized(mPackages) {
25174             final PackageParser.Package pkg = mPackages.get(packageName);
25175             if (pkg == null
25176                     || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
25177                             UserHandle.getUserId(callingUid))) {
25178                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25179                 throw new IllegalArgumentException("Unknown package: " + packageName);
25180             }
25181             IBinder ksh = ks.getToken();
25182             if (ksh instanceof KeySetHandle) {
25183                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
25184                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
25185             }
25186             return false;
25187         }
25188     }
25189 
25190     @Override
isPackageSignedByKeySetExactly(String packageName, KeySet ks)25191     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
25192         final int callingUid = Binder.getCallingUid();
25193         if (getInstantAppPackageName(callingUid) != null) {
25194             return false;
25195         }
25196         if (packageName == null || ks == null) {
25197             return false;
25198         }
25199         synchronized(mPackages) {
25200             final PackageParser.Package pkg = mPackages.get(packageName);
25201             if (pkg == null
25202                     || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
25203                             UserHandle.getUserId(callingUid))) {
25204                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25205                 throw new IllegalArgumentException("Unknown package: " + packageName);
25206             }
25207             IBinder ksh = ks.getToken();
25208             if (ksh instanceof KeySetHandle) {
25209                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
25210                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
25211             }
25212             return false;
25213         }
25214     }
25215 
deletePackageIfUnusedLPr(final String packageName)25216     private void deletePackageIfUnusedLPr(final String packageName) {
25217         PackageSetting ps = mSettings.mPackages.get(packageName);
25218         if (ps == null) {
25219             return;
25220         }
25221         if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
25222             // TODO Implement atomic delete if package is unused
25223             // It is currently possible that the package will be deleted even if it is installed
25224             // after this method returns.
25225             mHandler.post(new Runnable() {
25226                 public void run() {
25227                     deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
25228                             0, PackageManager.DELETE_ALL_USERS);
25229                 }
25230             });
25231         }
25232     }
25233 
25234     /**
25235      * Check and throw if the given before/after packages would be considered a
25236      * downgrade.
25237      */
checkDowngrade(PackageParser.Package before, PackageInfoLite after)25238     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
25239             throws PackageManagerException {
25240         if (after.versionCode < before.mVersionCode) {
25241             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25242                     "Update version code " + after.versionCode + " is older than current "
25243                     + before.mVersionCode);
25244         } else if (after.versionCode == before.mVersionCode) {
25245             if (after.baseRevisionCode < before.baseRevisionCode) {
25246                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25247                         "Update base revision code " + after.baseRevisionCode
25248                         + " is older than current " + before.baseRevisionCode);
25249             }
25250 
25251             if (!ArrayUtils.isEmpty(after.splitNames)) {
25252                 for (int i = 0; i < after.splitNames.length; i++) {
25253                     final String splitName = after.splitNames[i];
25254                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
25255                     if (j != -1) {
25256                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
25257                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25258                                     "Update split " + splitName + " revision code "
25259                                     + after.splitRevisionCodes[i] + " is older than current "
25260                                     + before.splitRevisionCodes[j]);
25261                         }
25262                     }
25263                 }
25264             }
25265         }
25266     }
25267 
25268     private static class MoveCallbacks extends Handler {
25269         private static final int MSG_CREATED = 1;
25270         private static final int MSG_STATUS_CHANGED = 2;
25271 
25272         private final RemoteCallbackList<IPackageMoveObserver>
25273                 mCallbacks = new RemoteCallbackList<>();
25274 
25275         private final SparseIntArray mLastStatus = new SparseIntArray();
25276 
MoveCallbacks(Looper looper)25277         public MoveCallbacks(Looper looper) {
25278             super(looper);
25279         }
25280 
register(IPackageMoveObserver callback)25281         public void register(IPackageMoveObserver callback) {
25282             mCallbacks.register(callback);
25283         }
25284 
unregister(IPackageMoveObserver callback)25285         public void unregister(IPackageMoveObserver callback) {
25286             mCallbacks.unregister(callback);
25287         }
25288 
25289         @Override
handleMessage(Message msg)25290         public void handleMessage(Message msg) {
25291             final SomeArgs args = (SomeArgs) msg.obj;
25292             final int n = mCallbacks.beginBroadcast();
25293             for (int i = 0; i < n; i++) {
25294                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
25295                 try {
25296                     invokeCallback(callback, msg.what, args);
25297                 } catch (RemoteException ignored) {
25298                 }
25299             }
25300             mCallbacks.finishBroadcast();
25301             args.recycle();
25302         }
25303 
invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)25304         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
25305                 throws RemoteException {
25306             switch (what) {
25307                 case MSG_CREATED: {
25308                     callback.onCreated(args.argi1, (Bundle) args.arg2);
25309                     break;
25310                 }
25311                 case MSG_STATUS_CHANGED: {
25312                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
25313                     break;
25314                 }
25315             }
25316         }
25317 
notifyCreated(int moveId, Bundle extras)25318         private void notifyCreated(int moveId, Bundle extras) {
25319             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
25320 
25321             final SomeArgs args = SomeArgs.obtain();
25322             args.argi1 = moveId;
25323             args.arg2 = extras;
25324             obtainMessage(MSG_CREATED, args).sendToTarget();
25325         }
25326 
notifyStatusChanged(int moveId, int status)25327         private void notifyStatusChanged(int moveId, int status) {
25328             notifyStatusChanged(moveId, status, -1);
25329         }
25330 
notifyStatusChanged(int moveId, int status, long estMillis)25331         private void notifyStatusChanged(int moveId, int status, long estMillis) {
25332             Slog.v(TAG, "Move " + moveId + " status " + status);
25333 
25334             final SomeArgs args = SomeArgs.obtain();
25335             args.argi1 = moveId;
25336             args.argi2 = status;
25337             args.arg3 = estMillis;
25338             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
25339 
25340             synchronized (mLastStatus) {
25341                 mLastStatus.put(moveId, status);
25342             }
25343         }
25344     }
25345 
25346     private final static class OnPermissionChangeListeners extends Handler {
25347         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
25348 
25349         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
25350                 new RemoteCallbackList<>();
25351 
OnPermissionChangeListeners(Looper looper)25352         public OnPermissionChangeListeners(Looper looper) {
25353             super(looper);
25354         }
25355 
25356         @Override
handleMessage(Message msg)25357         public void handleMessage(Message msg) {
25358             switch (msg.what) {
25359                 case MSG_ON_PERMISSIONS_CHANGED: {
25360                     final int uid = msg.arg1;
25361                     handleOnPermissionsChanged(uid);
25362                 } break;
25363             }
25364         }
25365 
addListenerLocked(IOnPermissionsChangeListener listener)25366         public void addListenerLocked(IOnPermissionsChangeListener listener) {
25367             mPermissionListeners.register(listener);
25368 
25369         }
25370 
removeListenerLocked(IOnPermissionsChangeListener listener)25371         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
25372             mPermissionListeners.unregister(listener);
25373         }
25374 
onPermissionsChanged(int uid)25375         public void onPermissionsChanged(int uid) {
25376             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
25377                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
25378             }
25379         }
25380 
handleOnPermissionsChanged(int uid)25381         private void handleOnPermissionsChanged(int uid) {
25382             final int count = mPermissionListeners.beginBroadcast();
25383             try {
25384                 for (int i = 0; i < count; i++) {
25385                     IOnPermissionsChangeListener callback = mPermissionListeners
25386                             .getBroadcastItem(i);
25387                     try {
25388                         callback.onPermissionsChanged(uid);
25389                     } catch (RemoteException e) {
25390                         Log.e(TAG, "Permission listener is dead", e);
25391                     }
25392                 }
25393             } finally {
25394                 mPermissionListeners.finishBroadcast();
25395             }
25396         }
25397     }
25398 
25399     private class PackageManagerNative extends IPackageManagerNative.Stub {
25400         @Override
getNamesForUids(int[] uids)25401         public String[] getNamesForUids(int[] uids) throws RemoteException {
25402             final String[] results = PackageManagerService.this.getNamesForUids(uids);
25403             // massage results so they can be parsed by the native binder
25404             for (int i = results.length - 1; i >= 0; --i) {
25405                 if (results[i] == null) {
25406                     results[i] = "";
25407                 }
25408             }
25409             return results;
25410         }
25411 
25412         // NB: this differentiates between preloads and sideloads
25413         @Override
getInstallerForPackage(String packageName)25414         public String getInstallerForPackage(String packageName) throws RemoteException {
25415             final String installerName = getInstallerPackageName(packageName);
25416             if (!TextUtils.isEmpty(installerName)) {
25417                 return installerName;
25418             }
25419             // differentiate between preload and sideload
25420             int callingUser = UserHandle.getUserId(Binder.getCallingUid());
25421             ApplicationInfo appInfo = getApplicationInfo(packageName,
25422                                     /*flags*/ 0,
25423                                     /*userId*/ callingUser);
25424             if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
25425                 return "preload";
25426             }
25427             return "";
25428         }
25429 
25430         @Override
getVersionCodeForPackage(String packageName)25431         public int getVersionCodeForPackage(String packageName) throws RemoteException {
25432             try {
25433                 int callingUser = UserHandle.getUserId(Binder.getCallingUid());
25434                 PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
25435                 if (pInfo != null) {
25436                     return pInfo.versionCode;
25437                 }
25438             } catch (Exception e) {
25439             }
25440             return 0;
25441         }
25442     }
25443 
25444     private class PackageManagerInternalImpl extends PackageManagerInternal {
25445         @Override
setLocationPackagesProvider(PackagesProvider provider)25446         public void setLocationPackagesProvider(PackagesProvider provider) {
25447             synchronized (mPackages) {
25448                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
25449             }
25450         }
25451 
25452         @Override
setVoiceInteractionPackagesProvider(PackagesProvider provider)25453         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
25454             synchronized (mPackages) {
25455                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
25456             }
25457         }
25458 
25459         @Override
setSmsAppPackagesProvider(PackagesProvider provider)25460         public void setSmsAppPackagesProvider(PackagesProvider provider) {
25461             synchronized (mPackages) {
25462                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
25463             }
25464         }
25465 
25466         @Override
setDialerAppPackagesProvider(PackagesProvider provider)25467         public void setDialerAppPackagesProvider(PackagesProvider provider) {
25468             synchronized (mPackages) {
25469                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
25470             }
25471         }
25472 
25473         @Override
setSimCallManagerPackagesProvider(PackagesProvider provider)25474         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
25475             synchronized (mPackages) {
25476                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
25477             }
25478         }
25479 
25480         @Override
setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider)25481         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
25482             synchronized (mPackages) {
25483                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
25484             }
25485         }
25486 
25487         @Override
grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId)25488         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
25489             synchronized (mPackages) {
25490                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
25491                         packageName, userId);
25492             }
25493         }
25494 
25495         @Override
grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId)25496         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
25497             synchronized (mPackages) {
25498                 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
25499                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
25500                         packageName, userId);
25501             }
25502         }
25503 
25504         @Override
grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId)25505         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
25506             synchronized (mPackages) {
25507                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
25508                         packageName, userId);
25509             }
25510         }
25511 
25512         @Override
setKeepUninstalledPackages(final List<String> packageList)25513         public void setKeepUninstalledPackages(final List<String> packageList) {
25514             Preconditions.checkNotNull(packageList);
25515             List<String> removedFromList = null;
25516             synchronized (mPackages) {
25517                 if (mKeepUninstalledPackages != null) {
25518                     final int packagesCount = mKeepUninstalledPackages.size();
25519                     for (int i = 0; i < packagesCount; i++) {
25520                         String oldPackage = mKeepUninstalledPackages.get(i);
25521                         if (packageList != null && packageList.contains(oldPackage)) {
25522                             continue;
25523                         }
25524                         if (removedFromList == null) {
25525                             removedFromList = new ArrayList<>();
25526                         }
25527                         removedFromList.add(oldPackage);
25528                     }
25529                 }
25530                 mKeepUninstalledPackages = new ArrayList<>(packageList);
25531                 if (removedFromList != null) {
25532                     final int removedCount = removedFromList.size();
25533                     for (int i = 0; i < removedCount; i++) {
25534                         deletePackageIfUnusedLPr(removedFromList.get(i));
25535                     }
25536                 }
25537             }
25538         }
25539 
25540         @Override
isPermissionsReviewRequired(String packageName, int userId)25541         public boolean isPermissionsReviewRequired(String packageName, int userId) {
25542             synchronized (mPackages) {
25543                 // If we do not support permission review, done.
25544                 if (!mPermissionReviewRequired) {
25545                     return false;
25546                 }
25547 
25548                 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
25549                 if (packageSetting == null) {
25550                     return false;
25551                 }
25552 
25553                 // Permission review applies only to apps not supporting the new permission model.
25554                 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
25555                     return false;
25556                 }
25557 
25558                 // Legacy apps have the permission and get user consent on launch.
25559                 PermissionsState permissionsState = packageSetting.getPermissionsState();
25560                 return permissionsState.isPermissionReviewRequired(userId);
25561             }
25562         }
25563 
25564         @Override
getPackageInfo( String packageName, int flags, int filterCallingUid, int userId)25565         public PackageInfo getPackageInfo(
25566                 String packageName, int flags, int filterCallingUid, int userId) {
25567             return PackageManagerService.this
25568                     .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
25569                             flags, filterCallingUid, userId);
25570         }
25571 
25572         @Override
getApplicationInfo( String packageName, int flags, int filterCallingUid, int userId)25573         public ApplicationInfo getApplicationInfo(
25574                 String packageName, int flags, int filterCallingUid, int userId) {
25575             return PackageManagerService.this
25576                     .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
25577         }
25578 
25579         @Override
getActivityInfo( ComponentName component, int flags, int filterCallingUid, int userId)25580         public ActivityInfo getActivityInfo(
25581                 ComponentName component, int flags, int filterCallingUid, int userId) {
25582             return PackageManagerService.this
25583                     .getActivityInfoInternal(component, flags, filterCallingUid, userId);
25584         }
25585 
25586         @Override
queryIntentActivities( Intent intent, int flags, int filterCallingUid, int userId)25587         public List<ResolveInfo> queryIntentActivities(
25588                 Intent intent, int flags, int filterCallingUid, int userId) {
25589             final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
25590             return PackageManagerService.this
25591                     .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
25592                             userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
25593         }
25594 
25595         @Override
getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)25596         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
25597                 int userId) {
25598             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
25599         }
25600 
25601         @Override
setDeviceAndProfileOwnerPackages( int deviceOwnerUserId, String deviceOwnerPackage, SparseArray<String> profileOwnerPackages)25602         public void setDeviceAndProfileOwnerPackages(
25603                 int deviceOwnerUserId, String deviceOwnerPackage,
25604                 SparseArray<String> profileOwnerPackages) {
25605             mProtectedPackages.setDeviceAndProfileOwnerPackages(
25606                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
25607         }
25608 
25609         @Override
isPackageDataProtected(int userId, String packageName)25610         public boolean isPackageDataProtected(int userId, String packageName) {
25611             return mProtectedPackages.isPackageDataProtected(userId, packageName);
25612         }
25613 
25614         @Override
isPackageEphemeral(int userId, String packageName)25615         public boolean isPackageEphemeral(int userId, String packageName) {
25616             synchronized (mPackages) {
25617                 final PackageSetting ps = mSettings.mPackages.get(packageName);
25618                 return ps != null ? ps.getInstantApp(userId) : false;
25619             }
25620         }
25621 
25622         @Override
wasPackageEverLaunched(String packageName, int userId)25623         public boolean wasPackageEverLaunched(String packageName, int userId) {
25624             synchronized (mPackages) {
25625                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
25626             }
25627         }
25628 
25629         @Override
grantRuntimePermission(String packageName, String name, int userId, boolean overridePolicy)25630         public void grantRuntimePermission(String packageName, String name, int userId,
25631                 boolean overridePolicy) {
25632             PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
25633                     overridePolicy);
25634         }
25635 
25636         @Override
revokeRuntimePermission(String packageName, String name, int userId, boolean overridePolicy)25637         public void revokeRuntimePermission(String packageName, String name, int userId,
25638                 boolean overridePolicy) {
25639             PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
25640                     overridePolicy);
25641         }
25642 
25643         @Override
getNameForUid(int uid)25644         public String getNameForUid(int uid) {
25645             return PackageManagerService.this.getNameForUid(uid);
25646         }
25647 
25648         @Override
requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, Intent origIntent, String resolvedType, String callingPackage, Bundle verificationBundle, int userId)25649         public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
25650                 Intent origIntent, String resolvedType, String callingPackage,
25651                 Bundle verificationBundle, int userId) {
25652             PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
25653                     responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
25654                     userId);
25655         }
25656 
25657         @Override
grantEphemeralAccess(int userId, Intent intent, int targetAppId, int ephemeralAppId)25658         public void grantEphemeralAccess(int userId, Intent intent,
25659                 int targetAppId, int ephemeralAppId) {
25660             synchronized (mPackages) {
25661                 mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
25662                         targetAppId, ephemeralAppId);
25663             }
25664         }
25665 
25666         @Override
isInstantAppInstallerComponent(ComponentName component)25667         public boolean isInstantAppInstallerComponent(ComponentName component) {
25668             synchronized (mPackages) {
25669                 return mInstantAppInstallerActivity != null
25670                         && mInstantAppInstallerActivity.getComponentName().equals(component);
25671             }
25672         }
25673 
25674         @Override
pruneInstantApps()25675         public void pruneInstantApps() {
25676             mInstantAppRegistry.pruneInstantApps();
25677         }
25678 
25679         @Override
getSetupWizardPackageName()25680         public String getSetupWizardPackageName() {
25681             return mSetupWizardPackage;
25682         }
25683 
setExternalSourcesPolicy(ExternalSourcesPolicy policy)25684         public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
25685             if (policy != null) {
25686                 mExternalSourcesPolicy = policy;
25687             }
25688         }
25689 
25690         @Override
isPackagePersistent(String packageName)25691         public boolean isPackagePersistent(String packageName) {
25692             synchronized (mPackages) {
25693                 PackageParser.Package pkg = mPackages.get(packageName);
25694                 return pkg != null
25695                         ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
25696                                         | ApplicationInfo.FLAG_PERSISTENT)) ==
25697                                 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
25698                         : false;
25699             }
25700         }
25701 
25702         @Override
getOverlayPackages(int userId)25703         public List<PackageInfo> getOverlayPackages(int userId) {
25704             final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
25705             synchronized (mPackages) {
25706                 for (PackageParser.Package p : mPackages.values()) {
25707                     if (p.mOverlayTarget != null) {
25708                         PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
25709                         if (pkg != null) {
25710                             overlayPackages.add(pkg);
25711                         }
25712                     }
25713                 }
25714             }
25715             return overlayPackages;
25716         }
25717 
25718         @Override
getTargetPackageNames(int userId)25719         public List<String> getTargetPackageNames(int userId) {
25720             List<String> targetPackages = new ArrayList<>();
25721             synchronized (mPackages) {
25722                 for (PackageParser.Package p : mPackages.values()) {
25723                     if (p.mOverlayTarget == null) {
25724                         targetPackages.add(p.packageName);
25725                     }
25726                 }
25727             }
25728             return targetPackages;
25729         }
25730 
25731         @Override
setEnabledOverlayPackages(int userId, @NonNull String targetPackageName, @Nullable List<String> overlayPackageNames)25732         public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
25733                 @Nullable List<String> overlayPackageNames) {
25734             synchronized (mPackages) {
25735                 if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
25736                     Slog.e(TAG, "failed to find package " + targetPackageName);
25737                     return false;
25738                 }
25739                 ArrayList<String> overlayPaths = null;
25740                 if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
25741                     final int N = overlayPackageNames.size();
25742                     overlayPaths = new ArrayList<>(N);
25743                     for (int i = 0; i < N; i++) {
25744                         final String packageName = overlayPackageNames.get(i);
25745                         final PackageParser.Package pkg = mPackages.get(packageName);
25746                         if (pkg == null) {
25747                             Slog.e(TAG, "failed to find package " + packageName);
25748                             return false;
25749                         }
25750                         overlayPaths.add(pkg.baseCodePath);
25751                     }
25752                 }
25753 
25754                 final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
25755                 ps.setOverlayPaths(overlayPaths, userId);
25756                 return true;
25757             }
25758         }
25759 
25760         @Override
resolveIntent(Intent intent, String resolvedType, int flags, int userId)25761         public ResolveInfo resolveIntent(Intent intent, String resolvedType,
25762                 int flags, int userId) {
25763             return resolveIntentInternal(
25764                     intent, resolvedType, flags, userId, true /*resolveForStart*/);
25765         }
25766 
25767         @Override
resolveService(Intent intent, String resolvedType, int flags, int userId, int callingUid)25768         public ResolveInfo resolveService(Intent intent, String resolvedType,
25769                 int flags, int userId, int callingUid) {
25770             return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
25771         }
25772 
25773         @Override
addIsolatedUid(int isolatedUid, int ownerUid)25774         public void addIsolatedUid(int isolatedUid, int ownerUid) {
25775             synchronized (mPackages) {
25776                 mIsolatedOwners.put(isolatedUid, ownerUid);
25777             }
25778         }
25779 
25780         @Override
removeIsolatedUid(int isolatedUid)25781         public void removeIsolatedUid(int isolatedUid) {
25782             synchronized (mPackages) {
25783                 mIsolatedOwners.delete(isolatedUid);
25784             }
25785         }
25786 
25787         @Override
getUidTargetSdkVersion(int uid)25788         public int getUidTargetSdkVersion(int uid) {
25789             synchronized (mPackages) {
25790                 return getUidTargetSdkVersionLockedLPr(uid);
25791             }
25792         }
25793 
25794         @Override
canAccessInstantApps(int callingUid, int userId)25795         public boolean canAccessInstantApps(int callingUid, int userId) {
25796             return PackageManagerService.this.canViewInstantApps(callingUid, userId);
25797         }
25798 
25799         @Override
hasInstantApplicationMetadata(String packageName, int userId)25800         public boolean hasInstantApplicationMetadata(String packageName, int userId) {
25801             synchronized (mPackages) {
25802                 return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
25803             }
25804         }
25805 
25806         @Override
notifyPackageUse(String packageName, int reason)25807         public void notifyPackageUse(String packageName, int reason) {
25808             synchronized (mPackages) {
25809                 PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
25810             }
25811         }
25812     }
25813 
25814     @Override
grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId)25815     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
25816         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
25817         synchronized (mPackages) {
25818             final long identity = Binder.clearCallingIdentity();
25819             try {
25820                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
25821                         packageNames, userId);
25822             } finally {
25823                 Binder.restoreCallingIdentity(identity);
25824             }
25825         }
25826     }
25827 
25828     @Override
grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId)25829     public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
25830         enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
25831         synchronized (mPackages) {
25832             final long identity = Binder.clearCallingIdentity();
25833             try {
25834                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
25835                         packageNames, userId);
25836             } finally {
25837                 Binder.restoreCallingIdentity(identity);
25838             }
25839         }
25840     }
25841 
enforceSystemOrPhoneCaller(String tag)25842     private static void enforceSystemOrPhoneCaller(String tag) {
25843         int callingUid = Binder.getCallingUid();
25844         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
25845             throw new SecurityException(
25846                     "Cannot call " + tag + " from UID " + callingUid);
25847         }
25848     }
25849 
isHistoricalPackageUsageAvailable()25850     boolean isHistoricalPackageUsageAvailable() {
25851         return mPackageUsage.isHistoricalPackageUsageAvailable();
25852     }
25853 
25854     /**
25855      * Return a <b>copy</b> of the collection of packages known to the package manager.
25856      * @return A copy of the values of mPackages.
25857      */
getPackages()25858     Collection<PackageParser.Package> getPackages() {
25859         synchronized (mPackages) {
25860             return new ArrayList<>(mPackages.values());
25861         }
25862     }
25863 
25864     /**
25865      * Logs process start information (including base APK hash) to the security log.
25866      * @hide
25867      */
25868     @Override
logAppProcessStartIfNeeded(String processName, int uid, String seinfo, String apkFile, int pid)25869     public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
25870             String apkFile, int pid) {
25871         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25872             return;
25873         }
25874         if (!SecurityLog.isLoggingEnabled()) {
25875             return;
25876         }
25877         Bundle data = new Bundle();
25878         data.putLong("startTimestamp", System.currentTimeMillis());
25879         data.putString("processName", processName);
25880         data.putInt("uid", uid);
25881         data.putString("seinfo", seinfo);
25882         data.putString("apkFile", apkFile);
25883         data.putInt("pid", pid);
25884         Message msg = mProcessLoggingHandler.obtainMessage(
25885                 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
25886         msg.setData(data);
25887         mProcessLoggingHandler.sendMessage(msg);
25888     }
25889 
getCompilerPackageStats(String pkgName)25890     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
25891         return mCompilerStats.getPackageStats(pkgName);
25892     }
25893 
getOrCreateCompilerPackageStats(PackageParser.Package pkg)25894     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
25895         return getOrCreateCompilerPackageStats(pkg.packageName);
25896     }
25897 
getOrCreateCompilerPackageStats(String pkgName)25898     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
25899         return mCompilerStats.getOrCreatePackageStats(pkgName);
25900     }
25901 
deleteCompilerPackageStats(String pkgName)25902     public void deleteCompilerPackageStats(String pkgName) {
25903         mCompilerStats.deletePackageStats(pkgName);
25904     }
25905 
25906     @Override
getInstallReason(String packageName, int userId)25907     public int getInstallReason(String packageName, int userId) {
25908         final int callingUid = Binder.getCallingUid();
25909         enforceCrossUserPermission(callingUid, userId,
25910                 true /* requireFullPermission */, false /* checkShell */,
25911                 "get install reason");
25912         synchronized (mPackages) {
25913             final PackageSetting ps = mSettings.mPackages.get(packageName);
25914             if (filterAppAccessLPr(ps, callingUid, userId)) {
25915                 return PackageManager.INSTALL_REASON_UNKNOWN;
25916             }
25917             if (ps != null) {
25918                 return ps.getInstallReason(userId);
25919             }
25920         }
25921         return PackageManager.INSTALL_REASON_UNKNOWN;
25922     }
25923 
25924     @Override
canRequestPackageInstalls(String packageName, int userId)25925     public boolean canRequestPackageInstalls(String packageName, int userId) {
25926         return canRequestPackageInstallsInternal(packageName, 0, userId,
25927                 true /* throwIfPermNotDeclared*/);
25928     }
25929 
canRequestPackageInstallsInternal(String packageName, int flags, int userId, boolean throwIfPermNotDeclared)25930     private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
25931             boolean throwIfPermNotDeclared) {
25932         int callingUid = Binder.getCallingUid();
25933         int uid = getPackageUid(packageName, 0, userId);
25934         if (callingUid != uid && callingUid != Process.ROOT_UID
25935                 && callingUid != Process.SYSTEM_UID) {
25936             throw new SecurityException(
25937                     "Caller uid " + callingUid + " does not own package " + packageName);
25938         }
25939         ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
25940         if (info == null) {
25941             return false;
25942         }
25943         if (info.targetSdkVersion < Build.VERSION_CODES.O) {
25944             return false;
25945         }
25946         String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
25947         String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
25948         if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
25949             if (throwIfPermNotDeclared) {
25950                 throw new SecurityException("Need to declare " + appOpPermission
25951                         + " to call this api");
25952             } else {
25953                 Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
25954                 return false;
25955             }
25956         }
25957         if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
25958             return false;
25959         }
25960         if (mExternalSourcesPolicy != null) {
25961             int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
25962             return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
25963         }
25964         return false;
25965     }
25966 
25967     @Override
getInstantAppResolverSettingsComponent()25968     public ComponentName getInstantAppResolverSettingsComponent() {
25969         return mInstantAppResolverSettingsComponent;
25970     }
25971 
25972     @Override
getInstantAppInstallerComponent()25973     public ComponentName getInstantAppInstallerComponent() {
25974         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25975             return null;
25976         }
25977         return mInstantAppInstallerActivity == null
25978                 ? null : mInstantAppInstallerActivity.getComponentName();
25979     }
25980 
25981     @Override
getInstantAppAndroidId(String packageName, int userId)25982     public String getInstantAppAndroidId(String packageName, int userId) {
25983         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
25984                 "getInstantAppAndroidId");
25985         enforceCrossUserPermission(Binder.getCallingUid(), userId,
25986                 true /* requireFullPermission */, false /* checkShell */,
25987                 "getInstantAppAndroidId");
25988         // Make sure the target is an Instant App.
25989         if (!isInstantApp(packageName, userId)) {
25990             return null;
25991         }
25992         synchronized (mPackages) {
25993             return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
25994         }
25995     }
25996 
canHaveOatDir(String packageName)25997     boolean canHaveOatDir(String packageName) {
25998         synchronized (mPackages) {
25999             PackageParser.Package p = mPackages.get(packageName);
26000             if (p == null) {
26001                 return false;
26002             }
26003             return p.canHaveOatDir();
26004         }
26005     }
26006 
getOatDir(PackageParser.Package pkg)26007     private String getOatDir(PackageParser.Package pkg) {
26008         if (!pkg.canHaveOatDir()) {
26009             return null;
26010         }
26011         File codePath = new File(pkg.codePath);
26012         if (codePath.isDirectory()) {
26013             return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
26014         }
26015         return null;
26016     }
26017 
deleteOatArtifactsOfPackage(String packageName)26018     void deleteOatArtifactsOfPackage(String packageName) {
26019         final String[] instructionSets;
26020         final List<String> codePaths;
26021         final String oatDir;
26022         final PackageParser.Package pkg;
26023         synchronized (mPackages) {
26024             pkg = mPackages.get(packageName);
26025         }
26026         instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
26027         codePaths = pkg.getAllCodePaths();
26028         oatDir = getOatDir(pkg);
26029 
26030         for (String codePath : codePaths) {
26031             for (String isa : instructionSets) {
26032                 try {
26033                     mInstaller.deleteOdex(codePath, isa, oatDir);
26034                 } catch (InstallerException e) {
26035                     Log.e(TAG, "Failed deleting oat files for " + codePath, e);
26036                 }
26037             }
26038         }
26039     }
26040 
getUnusedPackages(long downgradeTimeThresholdMillis)26041     Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
26042         Set<String> unusedPackages = new HashSet<>();
26043         long currentTimeInMillis = System.currentTimeMillis();
26044         synchronized (mPackages) {
26045             for (PackageParser.Package pkg : mPackages.values()) {
26046                 PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
26047                 if (ps == null) {
26048                     continue;
26049                 }
26050                 PackageDexUsage.PackageUseInfo packageUseInfo =
26051                       getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
26052                 if (PackageManagerServiceUtils
26053                         .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
26054                                 downgradeTimeThresholdMillis, packageUseInfo,
26055                                 pkg.getLatestPackageUseTimeInMills(),
26056                                 pkg.getLatestForegroundPackageUseTimeInMills())) {
26057                     unusedPackages.add(pkg.packageName);
26058                 }
26059             }
26060         }
26061         return unusedPackages;
26062     }
26063 }
26064 
26065 interface PackageSender {
sendPackageBroadcast(final String action, final String pkg, final Bundle extras, final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, final int[] userIds)26066     void sendPackageBroadcast(final String action, final String pkg,
26067         final Bundle extras, final int flags, final String targetPkg,
26068         final IIntentReceiver finishedReceiver, final int[] userIds);
sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted, boolean includeStopped, int appId, int... userIds)26069     void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
26070         boolean includeStopped, int appId, int... userIds);
26071 }
26072